﻿//#define DEVELOPER_MODE
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using System.Threading;
using Newtonsoft.Json.Linq;
using AdvancedDataGridView;

using BasePlatformCommon;
using BasePlatformNet;
using L9SubSet.lwf;
using System.Runtime.InteropServices;
using System.Diagnostics;
using BasePlatformCommon.devChain;
using System.Reflection;
using L9SubSet.WriteAddrPro;
using BasePlatformCom;
using System.Xml;
using BasePlatformCommon.lwf;

namespace L9SubSet
{
	public partial class Form_MainSet : Form
	{
        private const int BUTTON_GAP = 8;
        private bool developerEnable = false;           // 开发者模式
		private ZQConfig ZqConfig = null;				// ini配置辅助类
		private RVCardL9Config rvCardL9Config = null;	// 分控配置辅助类

		private bool m_LoadClockFromSub = false;		// 是否存文件中读取时钟index
		private bool m_LoadGrayFromSub = false;			// 是否从文件中读取灰度等级

		private string chipName = "";					// 芯片名称
		private string m_ChipInfoFileName;				// L9芯片配置文件
		private string[] m_MainMenuItemArray = { };		// 主菜单字符串
		private string[] m_ChildMenuItemArray = { };	// 子菜单字符串
		private string[] m_ChipTypeArray = { };			// 所有芯片名菜单
		private string[] m_ClockList = { };				// 时钟频率数组
		private string[] m_ColorModelist = { };			// 颜色模式数组
		private string[] m_GrayList;					// 灰度等级数组

		private string m_DxfFilePath;					// DXF文件路径
		private int m_HResolution;						// 水平分辨率
		private int m_VResolution;						// 垂直分辨率
		private int m_DxfSubControlNum;					// Dxf文件中的分控数量
		private int m_DxfLampNum;						// Dxf文件中的灯具数量

		private List<int> colorModeList = new List<int>(10);	// 颜色模式列表

		private Form_ProSet l9ProSetDlg = null;				// 高级设置窗体
		public Form_SelectSub m_FormSelectSub = null;		// 选择分控窗体
		public Form_SelectSubEx m_FormSelectSubEx = null;	// 选择分控

		private string config2012Ini = "";					// 配置文件 Config2012.ini 路径
        private string agentIni = "";						// 配置文件 Agent.ini 路径
        private string artDevChainIni = "";					// 配置文件 ArtDevChain.ini 路径

		private string initErrMessage = "";					// 初始化过程错误信息
		private bool initDone = false;						// 初始化结束标记

		private string addrMapFileType = "";				// 异形映射文件类型
		private string addrMapFilePath = "";				// 异形映射文件路径

		/***********************************************************************/

		private BaseCoreNet baseCoreNet = null;				// 底层通信平台引用（网口）	
		private BaseCoreCom baseCoreCom = null;				// 底层通信平台引用（串口）
		private ActivePath activePath = ActivePath.None;	// 当前活跃的数据通路

		/***********************************************************************/

		private bool addrEnableStateByInit = false;		// 由初始化判断的异形映射状态, 在 Form_MainSet_Shown 处执行
		private bool useSwitchByInit = false;			// 由初始化判断的多路交换机状态, 在 Form_MainSet_Shown 处执行

		private string switchConfigFilePath = "";		// 交换机配置文件路径

		// 用于右侧区域的展开/收起
		private double scaleUIX = 1.0;					// 横向系数
		private double scaleUIY = 1.0;					// 纵向系数
		private bool configPanelExpanded = false;		// 右侧配置面板展开标记
		private bool lampParaIsReadingFromFile = false;	// 正在从布线文件中读取灯具参数（保证读取过程不重入）

		private bool firstShow = true;					// 首次显示窗体标记

		private bool showTestTabEnable = false;			// 测试页显示标记
        private bool showMainTabEnable = true;          // 主控页显示标记
        private bool showOtherTabEnable = false;        // 其它页显示标记

        private bool AddrWriteTag = false;              // 写址标记

        private int nflgArray = -1;

        private bool useConfigPanelCheck = false;                           // 是否需要使用密码来展开配置菜单
        private string passwordString = "icolor,zc";                        // 密码

		// 委托定义与声明
		public delegate void SetLampParaIsReadingDelegate(bool isReading);
		public SetLampParaIsReadingDelegate setLampParaIsReadingDelegate;
		public delegate void UpdateOperationProgressDelegate(WriteEventArgs eArgs);
		public UpdateOperationProgressDelegate updateOperationProgressDelegate;
		public delegate void UpdateMainTreeDelegate(MainControl mainControl, List<ControlNode> controlNodeList);
		public UpdateMainTreeDelegate updateMainTreeDelegate;
		public delegate void DmxAddrOperPostHandleDelegate(DmxAddrOperEventArgs args);
		public DmxAddrOperPostHandleDelegate dmxAddrOperPostHandleDelegate;
		public delegate void CollapseConfigPanelDelegate();
		public CollapseConfigPanelDelegate collapseConfigPanelDelegate;
		public delegate void UpdateClearSubPositonProgressDelegate(int currentNum, int totalNum);
		public UpdateClearSubPositonProgressDelegate updateClearSubPositonProgressDelegate;
		public delegate void ShowTipMessageDelegate(string msg, string head, MessageBoxButtons button, MessageBoxIcon icon);
		public ShowTipMessageDelegate showTipMessageDelegate;

		// 事件定义与声明
		public event EventHandler<DmxAddrOperEventArgs> DmxAddrOperDoneEvent;
		public event EventHandler<EventArgs> ResetSubDoneEvent;
		public event EventHandler<EventArgs> ReachMaxPacketNumEvent;

		// OpenFileDialog 对话框路径保存
		public string lastPath_SysBackFile = "";						// 系统配置备份文件
		public string lastPath_SwitchConfigFile = "";					// 系统结构文件
		public string lastPath_SubFileConfig = "";						// 分控配置 - Sub文件
		public string lastPath_SubFileSend = "";						// 周期下发 - Sub文件
		public string lastPath_GridConfig_InputGridExcel = "";			// 子界面 GridConfig，网格数据文件
		public string lastPath_SelectSubEx_LwfConfigFile = "";			// 子界面 SelectSubEx，布线配置文件
		public string lastPath_ReceiverControl_UpdateSrcFile = "";		// 子界面 ReceiverControl，升级文件
		public string lastPath_StartAddrMap_AddrMapFile = "";			// 子界面 StartAddrMap，布线文件

		// 主控 DVI 状态模拟
		private int mainControlDviMode = 0;

		// 主控连接状态模拟
		private int mainControlConnected = 0;

		private string subSendApplyOrTest = "";			// sub 文件下发模式 - 应用|测试

		private bool autoSendSubEnable = false;			// 自动周期下发 sub 文件

		private bool switchCheckAction = true;			// 用于屏蔽 switchEnableCheckBox 的响应动作

		public string useInnerSwitchDataTip = "由系统文件指定（可另存为Json文件）";
		public string useInnerAddrDataTip = "由系统文件指定（可另存为lwf文件）";
		public string innerSwitchDataFilePath = "";
		public string innerAddrDataFilePath = "";

		private MainControl lastMainControl = null;							// 前次检测到的设备链根节点

		private int nodeRowHeight = 16;										// 表格行高

		private bool refreshMainTreeEnable = true;							// 在线检测设备树刷新使能
		
		private int mainTreeRefreshNum = 0;									// 在线检测设备数刷新次数

		private bool dmxSetting = false;									// 写入地址正在执行的标记（防止操作重入）

		private SystemTubeReader lwfSystemTubeReader = null;				// 灯点读取类
		
		private List<SubTubeData> subTubeDataList = null;					// 布线文件中的分控列表, 目前仅支持 lwf 格式

		private bool addrMapDataIsDownloading = false;						// 布线文件下载标记

		private bool addrMapDataIsClearing = false;							// 布线文件清除标记

		public  bool subDataIsDownloading = false;							// sub文件下载标记

        public LampCheckMode lastLampDetectMode {                           // 灯具巡检窗体 - 上次保存的灯具检测模式
            get { return lampDetectMode; }
            set {
                lampDetectMode = value;
                changeDetectMode();
            }
        }

		public bool saveLampCheckModeChecked = false;						// 灯具巡检窗体 - 保存检测模式 checkbox 状态

		public string lastCheckAccordingFilePath = "";						// 灯具巡检窗体 - 上次保存的检测结果文件路径

		private bool iBluePlayerIsPlaying = false;							// iBluePlayer播放标记

		private bool cmbChannelNumActionEnable = true;					// 辅助标记

		private bool chipJustChanged = false;								// 芯片类型切换标记

		private bool manualRadioJustSelected = false;						// 辅助标记

        private int userColorType = 255;                                    // 用户颜色设置（仅四色）

        private int defaultColorType = 0;                                   // 分控颜色设置（仅四色）

        /*******************************************************************************/

		private Form_SubDetail formSubDetail = null;						// 分控详细信息表

		private string section = "MainSet";									// 多语言文件配置节名称

		private string tip = "提示";											// MessageBox 题头

		private bool languageChangeEnable = true;							// 是否响应用户通过系统界面触发的语言更改命令

		private Dictionary<string, Form> formDictionary = new Dictionary<string, Form>();

		/*******************************************************************************/

        private Form_ReadLwfPara frmLwfPara = null;                         // 异形文件参数

        private int writeAddrMode = 0;                                      // 0-写址，1-写芯片参数，2-写芯片电流

        private byte[] chipConfig1, chipConfig2;                            // 芯片参数1区，芯片参数2区

        private int chipCurrentMode = 0;                                    // 电流档位 SM17500

        private LampCheckMode lampDetectMode = LampCheckMode.RealTime;

        private DetectType lampDetectType = DetectType.Normal;

        private bool isSettingDetectRDM = false;

        private bool autoDetectRDM = false;
        /*******************************************************************************/

		#region DLLImport

		[DllImport("user32.dll")]
		static extern IntPtr GetDC(IntPtr ptr);

		[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
		public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);

		[DllImport("gdi32.dll")]
		public static extern IntPtr CreateDC(
		string lpszDriver,	// driver name
		string lpszDevice,	// device name
		string lpszOutput,	// not used; should be NULL
		Int64 lpInitData	// optional printer data
		);

		[DllImport("gdi32.dll")]
		public static extern int GetDeviceCaps(
		IntPtr hdc,			// handle to DC
		int nIndex			// index of capability
		);

		[DllImport("user32.dll")]
		internal static extern bool SetProcessDPIAware();

		[DllImport("User32.dll")]
		private static extern bool SetForegroundWindow(IntPtr hWnd);

		#endregion

		// 构造函数
		public Form_MainSet()
		{
			InitializeComponent();

			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
			this.Font = new System.Drawing.Font(this.Font.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));

#if DEVELOPER_MODE
            developerEnable = true;
#endif
			initEnvironment();
		}

		// 初始化运行环境
		private void initEnvironment()
		{
			tip = LanguageOper.ReadValue("Common", "tipStr");

			ZqConfig = new ZQConfig();
			rvCardL9Config = new RVCardL9Config();
			l9ProSetDlg = new Form_ProSet(rvCardL9Config);

			// 配置文件路径
			config2012Ini = ZqConfig.GetAppPath() + @"\conf\Config2012.ini";
            agentIni = ZqConfig.GetAppPath() + @"\conf\Agent.ini";
            artDevChainIni = getAppPath() + @"\conf\artDevChain.ini";

			// 设置初始选择的 tab 页
			tabSetting.SelectedIndex = 0;

			// 菜单 - 系统配置 - 配置文件
			AddContextMenu("打开", contextMenuStrip_Sys.Items, openSysBackFile_Click);
			AddContextMenu("保存", contextMenuStrip_Sys.Items, saveSysBackFile_Click);
			AddContextMenu("另存为", contextMenuStrip_Sys.Items, saveOtherSysBackFile_Click);

			// 菜单 - 系统配置 - 布线文件
			AddContextMenu("打开", contextMenuStrip_AddrMap.Items, openAddrMapFile_Click);
			AddContextMenu("另存为", contextMenuStrip_AddrMap.Items, saveOtherAddrMapFile_Click);
			AddContextMenu("清除", contextMenuStrip_AddrMap.Items, clearAddrMapFile_Click);
			
			// 菜单 - 系统配置 - 系统结构文件
			AddContextMenu("新建", contextMenuStrip_Switch.Items, newSwitchConfigFile_Click);
			AddContextMenu("打开", contextMenuStrip_Switch.Items, openSwitchConfigFile_Click);
			AddContextMenu("编辑", contextMenuStrip_Switch.Items, editSwitchConfigFile_Click);
			AddContextMenu("另存为", contextMenuStrip_Switch.Items, saveOtherSwitchConfigFile_Click);
			AddContextMenu("清除", contextMenuStrip_Switch.Items, clearSwitchConfigFile_Click);

			// 菜单 - 分控设置 - 配置文件
			AddContextMenu("打开", contextMenuStrip_Sub.Items, openSub_Click);
			AddContextMenu("保存", contextMenuStrip_Sub.Items, saveToSub_Click);
			AddContextMenu("另存", contextMenuStrip_Sub.Items, otherSaveToSub_Click);

			// 菜单 - 测试 - 选择周期下发的 sub 文件
			AddContextMenu("打开", contextMenuStrip_Sub2.Items, selectSub4Send_Open);
			AddContextMenu("默认", contextMenuStrip_Sub2.Items, selectSub4Send_Default);

			// 菜单 - 查看在线检测详细信息
			AddContextMenu("查看灯具信息", contextMenuStrip_DetectDetail.Items, showDetectDetail);

			// 委托实例化
			setLampParaIsReadingDelegate = new SetLampParaIsReadingDelegate(setLampParaIsReading);
			updateOperationProgressDelegate = new UpdateOperationProgressDelegate(updateOperationProgress);
			updateMainTreeDelegate = new UpdateMainTreeDelegate(updateMainTree);
			dmxAddrOperPostHandleDelegate = new DmxAddrOperPostHandleDelegate(dmxAddrOperPostHandle);
			collapseConfigPanelDelegate = new CollapseConfigPanelDelegate(collapseConfigPanel);
			updateClearSubPositonProgressDelegate = new UpdateClearSubPositonProgressDelegate(updateClearSubPositonProgress);
			showTipMessageDelegate = new ShowTipMessageDelegate(showTipMessage);

			// 注册事件处理函数
			DmxAddrOperDoneEvent += dmxAddrOperDoneEventHandler;
			ResetSubDoneEvent += resetSubDoneEventHandler;
			ReachMaxPacketNumEvent += reachMaxPacketNumEventHandler;

			innerSwitchDataFilePath = ZqConfig.GetAppPath() + @"\conf\tmpSwitchData.json";
			innerAddrDataFilePath = ZqConfig.GetAppPath() + @"\conf\tmpAddrMapData.dat";

            #region 其他设置
            // 分控详细信息界面
            formSubDetail = new Form_SubDetail();

            // 异形文件参数界面
            frmLwfPara = new Form_ReadLwfPara(this);

            sysConfigGroupBox.Enabled = false;
            //grpNetSet.Visible = false;
            //btnArtNetTool.Visible = false;
            manualRadioButton.Enabled = false; // 暂时不允许手动排列设置

            // 异形开关仅通过是否有布线文件决定
            rbFromLwf.Enabled = false;
            rbManual.Enabled = false;

            // DVI 设置界面可见状态
            setShowMainTabEnable(false);

            // 其他界面可见状态
            setShowOtherTabEnable(false);

            // 展开配置菜单前密码检验
            useConfigPanelCheck = getConfigValue(agentIni, "configPanelCheck").Equals("true") ? true : false;
            passwordString = getConfigValue(agentIni, "passwordString");

            // 在线检测
            cmbDetectType.Items.Clear();
            cmbDetectType.Items.Add("常规");
            cmbDetectType.Items.Add("RDM");
            cmbDetectType.SelectedIndex = 0;

            cmbDetectMode.Items.Clear();
            cmbDetectMode.Items.Add("依据布线文件");
            cmbDetectMode.Items.Add("依据搜索结果");
            cmbDetectMode.Items.Add("实时检测");
            cmbDetectMode.SelectedIndex = 2;

            cmbDetectType.Enabled = false;
            cmbDetectMode.Enabled = false;

            #endregion

			#region Tab 系统配置初始化

			lwfSystemTubeReader = new SystemTubeReader();
			subTubeDataList = new List<SubTubeData>();

			// 设置异形与布线状态
			if (getConfigValue(agentIni, "addrMapEnable").Trim().Equals("true"))
			{

				addrMapFilePath = getConfigValue(agentIni, "addrMapFilePath");
				if (addrMapFilePath.Equals(""))
				{
					// 配置文件中未指定的布线文件
                    setConfigValue(agentIni, "addrMapEnable", "false");
				}
				else if (!File.Exists(addrMapFilePath))
				{
					// 配置文件中指定的布线文件不存在
					string formatStr = "配置文件中指定的布线文件 {0} 不存在, 请重新选择\n";
					if (LanguageOper.available == true)
					{
						formatStr = LanguageOper.ReadValue(section, "msgStr.0");
					}
					initErrMessage += string.Format(formatStr, addrMapFilePath);
					
					// 清除原有配置
					setConfigValue(agentIni, "addrMapEnable", "false");
					setConfigValue(agentIni, "addrMapFilePath", "");
					setConfigValue(agentIni, "addrMapFileType", "");
				}
				else
				{
					lastPath_StartAddrMap_AddrMapFile = (new FileInfo(addrMapFilePath)).DirectoryName;
					addrMapFileTextBox.Text = addrMapFilePath;
					addrMapFileTextBox.SelectionStart = addrMapFileTextBox.Text.Length;
					addrMapFileTextBox.ScrollToCaret();
					addrMapFileType = getConfigValue(agentIni, "addrMapFileType");
					if (addrMapFileType.Equals("lwf") || addrMapFileType.Equals("json") || addrMapFileType.Equals("dxf"))
					{
						// 参数完整 - 启用异形映射（设置 addrEnableStateByInit）
						addrEnableStateByInit = true;

						// 参数文件为 lwf 格式
						if (addrMapFileType.Equals("lwf"))
						{
                            fillSubTubDataList(addrMapFilePath);
                            //string xmlFile = ZqConfig.GetAppPath() + Path.DirectorySeparatorChar + "lwf-xml.tmp";
                            //LwfXmlRead.ReadXmlFormLwf(addrMapFilePath, xmlFile);
                            //subTubeDataList = lwfSystemTubeReader.readSystemTubeDataFormXml(xmlFile);
                            //if (File.Exists(xmlFile))
                            //{
                            //    try
                            //    {
                            //        File.Delete(xmlFile);
                            //    }
                            //    catch (Exception)
                            //    {
                            //    }
                            //}
						}
					}
					else
					{
						// 关闭异形映射（设置 addrEnableStateByInit）
						addrEnableStateByInit = false;
					}
				}
			}
			else
			{

				// 关闭异形映射（设置 addrEnableStateByInit）
				addrEnableStateByInit = false;

				addrMapFilePath = getConfigValue(agentIni, "addrMapFilePath");
				if (!File.Exists(addrMapFilePath))
				{
					// 配置文件中指定的布线文件不存在, 清除原有配置
					setConfigValue(agentIni, "addrMapFilePath", "");
					setConfigValue(agentIni, "addrMapFileType", "");
					addrMapFileType = "";
					addrMapFilePath = "";
				}
				else
				{
					lastPath_StartAddrMap_AddrMapFile = (new FileInfo(addrMapFilePath)).DirectoryName;
					addrMapFileType = getConfigValue(agentIni, "addrMapFileType");
					if (addrMapFileType.Equals("lwf") || addrMapFileType.Equals("json") || addrMapFileType.Equals("dxf"))
					{
						// 参数完整
					}
					else
					{
						// 参数不完整, 清除原有配置
						setConfigValue(agentIni, "addrMapFilePath", "");
						setConfigValue(agentIni, "addrMapFileType", "");
						addrMapFileType = "";
						addrMapFilePath = "";
					}

					addrMapFileTextBox.Text = addrMapFilePath;
					addrMapFileTextBox.SelectionStart = addrMapFileTextBox.Text.Length;
					addrMapFileTextBox.ScrollToCaret();
				}
			}

			// 设置多路交换机状态
			if (getConfigValue(agentIni, "useSwitch").Trim().Equals("true"))
			{
				switchEnableCheckBox.Checked = true;

				switchConfigFilePath = getConfigValue(agentIni, "switchConfigFilePath");
				if (switchConfigFilePath.Equals(""))
				{
					// 配置文件中未指定的系统结构文件
					switchEnableCheckBox.Checked = false;
				}
				else if (!File.Exists(switchConfigFilePath))
				{
					// 配置文件中指定的系统结构文件不存在
					switchEnableCheckBox.Checked = false;
					string formatStr = "配置文件中指定的系统结构文件 {0} 不存在, 请重新选择\n";
					if (LanguageOper.available == true)
					{
						formatStr = LanguageOper.ReadValue(section, "msgStr.1");
					}
					initErrMessage += string.Format(formatStr, switchConfigFilePath);
					
					// 清除原有配置
					setConfigValue(agentIni, "useSwitch", "false");
					setConfigValue(agentIni, "switchConfigFilePath", "");
				}
				else
				{
					lastPath_SwitchConfigFile = (new FileInfo(switchConfigFilePath)).DirectoryName;
					switchConfigFileTextBox.Text = switchConfigFilePath;
					switchConfigFileTextBox.SelectionStart = switchConfigFileTextBox.Text.Length;
					switchConfigFileTextBox.ScrollToCaret();
					
					// 参数完整 - 启用异形映射（设置 useSwitchByInit）
					useSwitchByInit = true;
				}
			}
			else
			{
				switchEnableCheckBox.Checked = false;

				// 关闭多路交换机（设置 useSwitchByInit）
				useSwitchByInit = false;

				switchConfigFilePath = getConfigValue(agentIni, "switchConfigFilePath");
				if (!File.Exists(switchConfigFilePath))
				{
					// 配置文件中指定的系统结构文件不存在, 清除原有配置
					setConfigValue(agentIni, "switchConfigFilePath", "");
				}
				else
				{
					switchConfigFileTextBox.Text = switchConfigFilePath;
					switchConfigFileTextBox.SelectionStart = switchConfigFileTextBox.Text.Length;
					switchConfigFileTextBox.ScrollToCaret();
				}
			}
            

			#endregion

			#region Tab 分控设置初始化

			// 加载 \conf\defaultL9.sub
			string defaultL9Path = ZqConfig.GetAppPath() + @"\conf\defaultL9.sub";

			// defaultL9.sub 文件存在
			if (File.Exists(defaultL9Path))
			{
				loadFromSub(defaultL9Path);
			}
			// defaultL9.sub 文件不存在
			else
			{
				rvCardL9Config.InitDefault();		// 加载默认的L9_Sub
			}

			// 初始化芯片菜单
			initChipMenu();

			// 更新主界面芯片名称
			showDefaultChipType();

			// 初始化分控设置界面信息
			initChipSetTab();

			contextMenuStrip_Sub.Items[1].Enabled = false;	// 保存
			contextMenuStrip_Sub.Items[2].Enabled = true;	// 另存

			// 触发端口带载参数合法性检查
			//cmbChannelNum.SelectedIndexChanged += cmbChannelNum_SelectedIndexChanged;

			// 根据配置文件初始化周期下发 sub 文件的界面状态（不涉及底层）
			string subDataName = getConfigValue(agentIni, "subDataName");
			sub4SendTextBox.Text = subDataName;
			if (getConfigValue(agentIni, "sendSubEnable").Trim().ToLower().Equals("true") && !getConfigValue(agentIni, "subDataName").Trim().ToLower().Equals(""))
			{
				if (File.Exists(subDataName))
				{
					sendSubButton.Text = "停止下发";
					if (LanguageOper.available == true)
					{
						sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Stop");
					}
					autoSendSubEnable = true;
				}
				else if (File.Exists(ZqConfig.GetAppPath() + @"\conf\" + subDataName))
				{
					sub4SendTextBox.Text = subDataName;
					sendSubButton.Text = "停止下发";
					if (LanguageOper.available == true)
					{
						sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Stop");
					}
					autoSendSubEnable = true;
				}
				else
				{
					sendSubButton.Text = "开始下发";
					if (LanguageOper.available == true)
					{
						sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Start");
					}
					autoSendSubEnable = false;
				}
			}
			else
			{
				sendSubButton.Text = "开始下发";
				if (LanguageOper.available == true)
				{
					sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Start");
				}
				autoSendSubEnable = false;
			}
			
			sub4SendTextBox.SelectionStart = sub4SendTextBox.Text.Length;
			sub4SendTextBox.ScrollToCaret();

			// 分控已设置异形数据
			if (getConfigValue(agentIni, "subHasSetAddrMap").Trim().ToLower().Equals("true"))
			{
				subHasConfigMapDataCheckBox.Checked = true;
				rvCardL9Config.SetSysControlMode(0);	// 勾选，RVCardL9Config 标志位 sysControlMode = 0
			}
			else
			{
				subHasConfigMapDataCheckBox.Checked = false;
				rvCardL9Config.SetSysControlMode(1);	// 不勾选，RVCardL9Config 标志位 sysControlMode = 1
			}

			// 保留分控位置信息
			if (getConfigValue(agentIni, "saveSubPosition").Trim().ToLower().Equals("true"))
			{
				saveSubPosInfoCheckBox.Checked = true;
			}
			else
			{
				saveSubPosInfoCheckBox.Checked = false;
			}

			#endregion

            #region Tab 快速设置
            cmbChannelNum.Items.Clear();
            cmbChannelNum.Items.AddRange(new object[] { 128, 256, 384, 512, 768, 1024, 1536, 2048, 3072 });
            #endregion

			#region Tab 主控制器
			#endregion

			#region Tab 其他

			dmxTypeComboBox.Items.Add("不支持");
			dmxTypeComboBox.Items.Add("iColor");
			dmxTypeComboBox.Items.Add("UCS512A/TM512");
			dmxTypeComboBox.Items.Add("UCS512C");
			dmxTypeComboBox.Items.Add("SM1651X");
            dmxTypeComboBox.Items.Add("ZD512-LP");
            dmxTypeComboBox.Items.Add("UCS512D");
            dmxTypeComboBox.Items.Add("UCS512E");
            dmxTypeComboBox.Items.Add("SM17500");
			if (LanguageOper.available == true)
			{
				dmxTypeComboBox.Items[0] = LanguageOper.ReadValue(section, "unSupport");
			}
			dmxTypeComboBox.SelectedIndex = 1;
            //writeAddrProButton.Enabled = false;
            //lightChannelTextBox.Enabled = false;
            //lightChannelTextBox.Text = "4";
            #endregion

			#region Tab 测试

			mainControlStatusComboBox.Items.Add("不支持");
			mainControlStatusComboBox.Items.Add("正常");
			mainControlStatusComboBox.Items.Add("错误");
			mainControlStatusComboBox.Items.Add("检测值");
			mainControlStatusComboBox.SelectedIndex = 3;
			mainControlDviMode = 3;

			mainControlConnectedComboBox.Items.Add("未连接");
			mainControlConnectedComboBox.Items.Add("已连接 1");
			mainControlConnectedComboBox.Items.Add("已连接 2");
			mainControlConnectedComboBox.Items.Add("已连接 3");
			mainControlConnectedComboBox.Items.Add("检测值");
			mainControlConnectedComboBox.SelectedIndex = 4;
			mainControlConnected = 4;

			languageComboBox.Items.Add("CHS");
			languageComboBox.Items.Add("EN");
            //languageComboBox.Items.Add("CHT");	// todo

            #endregion

            #region 屏幕显示适配
            /*
			// 获取系统 DPI
			try
			{
				SetProcessDPIAware();		// 重要
				IntPtr screenDC = GetDC(IntPtr.Zero);
				const int LOGPIXELSX = 88;
				const int LOGPIXELSY = 90;
				int dpi_x = GetDeviceCaps(screenDC, LOGPIXELSX);
				int dpi_y = GetDeviceCaps(screenDC, LOGPIXELSY);
				scaleUIX = dpi_x / 96.0;	// 横向系数
				scaleUIY = dpi_y / 96.0;	// 纵向系数
				ReleaseDC(IntPtr.Zero, screenDC);
			}
			catch (Exception)
			{
				// 获取过程异常 - 没有管理员权限
				scaleUIX = 1.0;		// 横向系数
				scaleUIY = 1.0;		// 纵向系数
			}

			infoSplitContainer.Panel2Collapsed = true;
			this.Width = (int)(520 * scaleUIX);
			*/
            Graphics graphics = this.CreateGraphics();
            scaleUIX = graphics.DpiX / 96.0;
            scaleUIY = graphics.DpiY / 96.0;
			infoSplitContainer.Panel2Collapsed = true;
            this.Size = new Size((int)(scaleUIX * 520), (int)(scaleUIY * this.Size.Height));
			
			#endregion 屏幕显示适配

			#region 设置本地化语言
			
			if (LanguageOper.available == true)
			{
				setLanguageText();
			}
			
			#endregion

			initDone = true;
		}

		// 设置底层通信平台引用
		public void setBaseCoreNet(BaseCoreNet baseCoreNet, BaseCoreCom baseCoreCom)
		{
			this.baseCoreNet = baseCoreNet;
            this.baseCoreNet.userColorChangedHandle += userColorChanged;
            this.baseCoreNet.UpdateStatusStr += onUpdateStatusStr;
            this.baseCoreCom = baseCoreCom;
		}

		// 展开/收起右侧区域（右侧区域默认为关闭）
		private void splitButton_Click(object sender, EventArgs e)
		{
			// 展开右侧区域
			if (infoSplitContainer.Panel2Collapsed == true)
			{
				expandConfigPanel();
                autoDetectRDM = false;
			}
			// 收起右侧区域
			else
			{
				collapseConfigPanel();
                autoDetectRDM = true;
			}
            setAutoDetectEnableRDM();
		}

		// 展开右侧区域
		public void expandConfigPanel()
		{
			if (iBluePlayerIsPlaying)
			{
				string msg = "iBluePlayer 有内容在播放，无法同时进行配置操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.2");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				return;
			}

            if (useConfigPanelCheck)
            {
                if (!showPassword()) {
                    return;
                }
            }
            
			int panel1Width = (int)(520 * scaleUIX);
			int panel2Width = (int)(430 * scaleUIX);
			int splitterWidth = (int)(4 * scaleUIX);
			Size newSize = new Size(this.Width + panel2Width + splitterWidth, this.Height);
			this.Size = newSize;
			infoSplitContainer.Panel2Collapsed = false;
			configPanelExpanded = true;
			infoSplitContainer.SplitterDistance = (int)(490 * scaleUIX);
		}

		// 收起右侧区域
		public void collapseConfigPanel()
		{
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate()
                {
                    this.collapseConfigPanel();
                }));
            }
            else
            {
                if (infoSplitContainer.Panel2Collapsed == false)
                {
                    int panel2Width = (int)(430 * scaleUIX);
                    int splitterWidth = (int)(4 * scaleUIX);
                    Size newSize = new Size(this.Width - panel2Width - splitterWidth, this.Height);
                    infoSplitContainer.Panel2Collapsed = true;
                    this.Size = newSize;
                    configPanelExpanded = false;
                    infoSplitContainer.SplitterDistance = (int)(490 * scaleUIX);
                }
            }
		}

		// 窗体显示后处理
		private void Form_MainSet_Shown(object sender, EventArgs e)
		{
			// 首次打开
			if (firstShow == true)
			{
				// 根据 addrEnableStateByInit 开启或关闭异形映射
				if (addrEnableStateByInit == true)
				{
					setAddrMapEnable(true);
				}
				else
				{
					setAddrMapEnable(false);
				}
				addrEnableStateByInit = false;

				// 根据 useSwitchByInit 开启或关闭交换机
				if (useSwitchByInit == true)
				{
					switchConfigButton.Enabled = true;
					switchConfigFileTextBox.Enabled = true;
					if (baseCoreNet != null)
					{
						string res = baseCoreNet.readSwitchConfigFileJson(switchConfigFileTextBox.Text.Trim());
						if (res.Equals("success"))
						{
							baseCoreNet.setUseSwitch(true);
						}
						else
						{
							baseCoreNet.setUseSwitch(false);
						}
					}
				}
				else
				{
					switchConfigButton.Enabled = false;
					switchConfigFileTextBox.Enabled = false;
					if (baseCoreNet != null)
					{
						baseCoreNet.setUseSwitch(false);
					}
				}
				useSwitchByInit = false;

				if (baseCoreNet != null)
				{
					// 设置 “保存到固定网段” 勾选状态
					useSocketCheckBox.Checked = baseCoreNet.getSendDataUseSocket();
					
					// 设置 socket 发包模式选择状态
                    SocketSendMode socketSendMode = baseCoreNet.getSocketSendMode();
                    if (socketSendMode == SocketSendMode.Sync) {
                        socketSyncRadioButton.Checked = true;
                        socketAsynRadioButton.Checked = false;
                    } else {
                        socketSyncRadioButton.Checked = false;
                        socketAsynRadioButton.Checked = true;
                    }

                    // 设置 socket 发包模式选择状态
                    var netSpeed = baseCoreNet.GetNetSpeed();
                    if (netSpeed == NetSpeed.GigaByte)
                    {
                        radioGigaByte.Checked = true;
                        radioHundredMegaByte.Checked = false;
                    }
                    else
                    {
                        radioGigaByte.Checked = false;
                        radioHundredMegaByte.Checked = true;
                    }
				}

				// 提示初始化过程中的错误信息
				if (!initErrMessage.Equals(""))
				{
					MessageBoxEx.Show(this, initErrMessage, tip, MessageBoxButtons.OK, MessageBoxIcon.Warning);
					initErrMessage = "";
				}
			}

            if (baseCoreNet != null) {
                updateMapModeAndColorString();
            }
            
			if (LanguageOper.available == true)
			{
				if (LanguageOper.LocalLanguage == LanguageEnum.CHS)
				{
					languageComboBox.SelectedIndex = 0;
				}
				else if (LanguageOper.LocalLanguage == LanguageEnum.EN)
				{
					languageComboBox.SelectedIndex = 1;
				}
				else if (LanguageOper.LocalLanguage == LanguageEnum.CHT)
				{
					languageComboBox.SelectedIndex = 2;
				}
			}
			else
			{
				languageComboBox.SelectedIndex = 0;
			}

            cmbDetectType.SelectedIndex = 1;

            autoDetectRDM = true;
            setAutoDetectEnableRDM();

			this.BringToFront();
			this.TopMost = true;
			this.TopMost = false;

			firstShow = false;
		}

		// 窗体关闭前处理
		private void Form_MainSet_FormClosing(object sender, FormClosingEventArgs e)
		{
            autoDetectRDM = false;
            setAutoDetectEnableRDM();
			if (addrMapDataIsDownloading == true)
			{
				string msg = "正在下载布线文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.3");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				e.Cancel = true;
			}
			else if (addrMapDataIsClearing == true)
			{
				string msg = "正在清除布线文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.4");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				e.Cancel = true;
			}
			else if (subDataIsDownloading == true)
			{
				string msg = "正在下载 sub 文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.5");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				e.Cancel = true;
			}

			cmbChannelNumActionEnable = false;
			if (checkFactLampNum() == false)
			{
				e.Cancel = true;
				cmbChannelNumActionEnable = true;
			}

			// 保存当前配置至 defaultL9.sub
			saveCurrentChipConfig();

			// 保存当前配置至用户指定的配置文件（按需）
			string userL9Path = subFileNameTextBox.Text;
			if (!userL9Path.Equals(""))
			{
				try
				{
					rvCardL9Config.SaveToSub(userL9Path, 0x080200);
				}
				catch (Exception ex)
				{
					string msg = string.Format("保存 {0} 失败", userL9Path);
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.6"), userL9Path); ;
					}
					Console.WriteLine(ex.Message + ex.StackTrace);
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		// 设置 iBluePlayer 播放状态
		public void setIBluePlayerPlayingState(bool playing)
		{
			iBluePlayerIsPlaying = playing;
		}

		// 获取配置面板展开状态
		public bool getConfigPanelExpanded()
		{
			return configPanelExpanded;
		}

		// 设置测试面板可见状态
		public void setShowTestTabEnable(bool showTestTabEnableValue) {
            this.showTestTabEnable = showTestTabEnableValue;
#if DEBUG
            this.showTestTabEnable = true;
#endif
            setShowTabState();
		}

        // 设置主控面板可见状态
        public void setShowMainTabEnable(bool showMainTabEnableValue) {
            this.showMainTabEnable = false; // 不可见
            setShowTabState();
        }

        // 设置其它面板可见状态
        public void setShowOtherTabEnable(bool showOtherTabEnableValue) {
            this.showOtherTabEnable = false; // 不可见
            setShowTabState();
        }

        private void setShowTabState() {
            if (InvokeRequired) {
                this.setShowTabState();
            } else {
                this.pageDVI.Parent = null;
                this.pageOther.Parent = null;
                this.pageTest.Parent = null;
                if (showMainTabEnable) {
                    this.pageDVI.Parent = this.tabSetting;
                }
                if (showOtherTabEnable) {
                    this.pageOther.Parent = this.tabSetting;
                }
                if (showTestTabEnable) {
                    this.pageTest.Parent = this.tabSetting;
                }
            }
        }

		// 设置本地化语言
		public void setLanguageText()
		{
			if (LanguageOper.available == false)
			{
				return;
			}

			LanguageOper.SetCurrentCulture();

			tip = LanguageOper.ReadValue("Common", "tipStr");

			// 界面控件文字
			this.Text = LanguageOper.ReadValue(section, "mainSet.Text");
            //expandToSubButton.Text = LanguageOper.ReadValue(section, "expandToSubButton.Text");
            //subDetailButton.Text = LanguageOper.ReadValue(section, "subDetailButton.Text");
            //lampDetailButton.Text = LanguageOper.ReadValue(section, "lampDetailButton.Text");
			//resetPacketNumButton.Text = LanguageOper.ReadValue(section, "resetPacketNumButton.Text");
			splitButton.Text = LanguageOper.ReadValue(section, "splitButton.Text");

			// 设备树 - 列头
			mainTreeGridView.Columns[0].HeaderText = LanguageOper.ReadValue(section, "mainTreeGridView.HeaderText.0");
			mainTreeGridView.Columns[1].HeaderText = LanguageOper.ReadValue(section, "mainTreeGridView.HeaderText.1");
			mainTreeGridView.Columns[3].HeaderText = LanguageOper.ReadValue(section, "mainTreeGridView.HeaderText.2");

			// 设备树 - 上下文菜单项
			contextMenuStrip_DetectDetail.Items[0].Text = LanguageOper.ReadValue(section, "contextDetectDetail.ItemsText.0");

			#region 系统配置


			// 布线文件 - 菜单项
			contextMenuStrip_AddrMap.Items[0].Text = LanguageOper.ReadValue(section, "contextAddrMap.ItemsText.0");
			contextMenuStrip_AddrMap.Items[1].Text = LanguageOper.ReadValue(section, "contextAddrMap.ItemsText.1");
			//contextMenuStrip_AddrMap.Items[2].Text = LanguageOper.ReadValue(section, "contextAddrMap.ItemsText.2");

			// 系统结构文件 - 菜单项
			contextMenuStrip_Switch.Items[0].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.0");
			contextMenuStrip_Switch.Items[1].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.1");
			contextMenuStrip_Switch.Items[2].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.2");
			contextMenuStrip_Switch.Items[3].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.3");
			contextMenuStrip_Switch.Items[4].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.4");

			// Tab 题头
            if (pageCommon != null && pageCommon.Parent != null) {
                pageCommon.Text = LanguageOper.ReadValue(section, "pageCommon.Text");
            }
            if (pageAdvance != null && pageAdvance.Parent != null) {
                pageAdvance.Text = LanguageOper.ReadValue(section, "pageAdvance.Text");
            }
            if (pageLamp != null && pageLamp.Parent != null) {
                pageLamp.Text = LanguageOper.ReadValue(section, "pageLamp.Text");
            }
            if (pageDVI != null && pageDVI.Parent != null) {
                pageDVI.Text = LanguageOper.ReadValue(section, "pageDVI.Text");
            }
            if (pageOther != null && pageOther.Parent != null) {
                pageOther.Text = LanguageOper.ReadValue(section, "pageOther.Text");
            }
            if (pageTest != null && pageTest.Parent != null) {
                pageTest.Text = LanguageOper.ReadValue(section, "pageTest.Text");
            }

			// 界面控件文字
			addrMapGroupBox.Text = LanguageOper.ReadValue(section, "addrMapGroupBox.Text");
			addrMapButton.Text = LanguageOper.ReadValue(section, "addrMapButton.Text");
			downloadLwfButton.Text = LanguageOper.ReadValue(section, "downloadLwfButton.Text");
			#endregion

			#region 分控设置

			// 分控配置文件 - 菜单项
			contextMenuStrip_Sub.Items[0].Text = LanguageOper.ReadValue(section, "contextSub.ItemsText.0");
			contextMenuStrip_Sub.Items[1].Text = LanguageOper.ReadValue(section, "contextSub.ItemsText.1");
			contextMenuStrip_Sub.Items[2].Text = LanguageOper.ReadValue(section, "contextSub.ItemsText.2");

			// 界面控件文字
			subConfigGroupBox.Text = LanguageOper.ReadValue(section, "subConfigGroupBox.Text");
			loadSubButton.Text = LanguageOper.ReadValue(section, "loadSubButton.Text");
			lampParaGroupBox.Text = LanguageOper.ReadValue(section, "lampParaGroupBox.Text");
			chipNameStaticLabel.Text = LanguageOper.ReadValue(section, "chipNameStaticLabel.Text");
			regularRadioButton.Text = LanguageOper.ReadValue(section, "regularRadioButton.Text");
			manualRadioButton.Text = LanguageOper.ReadValue(section, "manualRadioButton.Text");
            manualSetButton.Text = LanguageOper.ReadValue(section, "manualSetButton.Text");
            regularRadioButton2.Text = LanguageOper.ReadValue(section, "regularRadioButton.Text");
            manualRadioButton2.Text = LanguageOper.ReadValue(section, "manualRadioButton.Text");
            manualSetButton2.Text = LanguageOper.ReadValue(section, "manualSetButton.Text");
			applySubButton.Text = LanguageOper.ReadValue(section, "applySubButton.Text");
			testSubButton.Text = LanguageOper.ReadValue(section, "testSubButton.Text");
			subLoadGroupBox.Text = LanguageOper.ReadValue(section, "subLoadGroupBox.Text");
			maxPointsLabel.Text = LanguageOper.ReadValue(section, "maxPointsLabel.Text");
			maxLoadLabel.Text = LanguageOper.ReadValue(section, "maxLoadLabel.Text");
			maxChannelTipLabel.Text = LanguageOper.ReadValue(section, "maxChannelTipLabel.Text");
			maxLoadTipLabel.Text = LanguageOper.ReadValue(section, "maxLoadTipLabel.Text");
			checkSubButton.Text = LanguageOper.ReadValue(section, "checkSubButton.Text");
			performGroupBox.Text = LanguageOper.ReadValue(section, "performGroupBox.Text");
			clockFreqTipLabel.Text = LanguageOper.ReadValue(section, "clockFreqTipLabel.Text");
			greyTipLabel.Text = LanguageOper.ReadValue(section, "greyTipLabel.Text");
			gammaTipLabel.Text = LanguageOper.ReadValue(section, "gammaTipLabel.Text");
			clockDutyTipLabel.Text = LanguageOper.ReadValue(section, "clockDutyTipLabel.Text");
			lowGreyTipLabel.Text = LanguageOper.ReadValue(section, "lowGreyTipLabel.Text");
			startGreyTipLabel.Text = LanguageOper.ReadValue(section, "startGreyTipLabel.Text");
            grpChannelSet.Text = LanguageOper.ReadValue(section, "grpChannelSet.Text");
            rbFromLwf.Text = LanguageOper.ReadValue(section, "rbFromLwf.Text");
            rbManual.Text = LanguageOper.ReadValue(section, "rbManual.Text");
            grpChannelSet2.Text = LanguageOper.ReadValue(section, "grpChannelSet.Text");
            rbFromLwf2.Text = LanguageOper.ReadValue(section, "rbFromLwf.Text");
            rbManual2.Text = LanguageOper.ReadValue(section, "rbManual.Text");
			if (LanguageOper.LocalLanguage != LanguageEnum.EN)
			{
				lowGreyTipLabel.Location = new Point(165, 60);
				startGreyTipLabel.Location = new Point(189, 87);
			}
			else
			{
				lowGreyTipLabel.Location = new Point(135, 60);
				startGreyTipLabel.Location = new Point(166, 87);
			}
			proSetButton.Text = LanguageOper.ReadValue(section, "proSetButton.Text");
			subHasConfigMapDataCheckBox.Text = LanguageOper.ReadValue(section, "subHasConfigMapDataCheckBox.Text");
			saveSubPosInfoCheckBox.Text = LanguageOper.ReadValue(section, "saveSubPosInfoCheckBox.Text");
			viewManualColorListButton.Text = LanguageOper.ReadValue(section, "viewManualColorListButton.Text");

			#endregion

			#region 其他

			dmxGroupBox.Text = LanguageOper.ReadValue(section, "dmxGroupBox.Text");
			dmxChipTypeLabel.Text = LanguageOper.ReadValue(section, "dmxChipTypeLabel.Text");
			dmxFirstTubeNoLabel.Text = LanguageOper.ReadValue(section, "dmxFirstTubeNoLabel.Text");
			dmxTubeChannelLabel.Text = LanguageOper.ReadValue(section, "dmxTubeChannelLabel.Text");
			dmxFirstAddrLabel.Text = LanguageOper.ReadValue(section, "dmxFirstAddrLabel.Text");
			if (LanguageOper.LocalLanguage != LanguageEnum.EN)
			{
				dmxChipTypeLabel.Location = new Point(24, 25);
				dmxFirstTubeNoLabel.Location = new Point(24, 59);
				dmxTubeChannelLabel.Location = new Point(12, 87);
				dmxFirstAddrLabel.Location = new Point(18, 115);
			}
			else
			{
				dmxChipTypeLabel.Location = new Point(27, 25);
				dmxFirstTubeNoLabel.Location = new Point(2, 59);
				dmxTubeChannelLabel.Location = new Point(8, 87);
				dmxFirstAddrLabel.Location = new Point(20, 115);
			}
			usePin4CheckBox.Text = LanguageOper.ReadValue(section, "usePin4CheckBox.Text");
			writeSameAddrCheckBox.Text = LanguageOper.ReadValue(section, "writeSameAddrCheckBox.Text");
			writeAddrProButton.Text = LanguageOper.ReadValue(section, "writeAddrProButton.Text");
			dmxSaveButton.Text = LanguageOper.ReadValue(section, "dmxSaveButton.Text");
			dmxClearButton.Text = LanguageOper.ReadValue(section, "dmxClearButton.Text");
			debugToolGroupBox.Text = LanguageOper.ReadValue(section, "debugToolGroupBox.Text");
			readWriteBinButton.Text = LanguageOper.ReadValue(section, "readWriteBinButton.Text");
            mainControlGroupBox.Text = LanguageOper.ReadValue(section, "mainControlGroupBox.Text");
            chbShowMainControl.Text = LanguageOper.ReadValue(section, "chbShowMainControl.Text");
            radioGigaByte.Text = LanguageOper.ReadValue(section, "radioGigaByte.Text");
            radioHundredMegaByte.Text = LanguageOper.ReadValue(section, "radioHundredMegaByte.Text");

			#endregion

			#region 测试

			// Sub文件 - 菜单项
			contextMenuStrip_Sub2.Items[0].Text = LanguageOper.ReadValue(section, "contextMenuStrip_Sub2.ItemsText.0");
			contextMenuStrip_Sub2.Items[1].Text = LanguageOper.ReadValue(section, "contextMenuStrip_Sub2.ItemsText.1");

			// 下拉列表项
			mainControlStatusComboBox.Items[0] = LanguageOper.ReadValue(section, "unSupport");
			mainControlStatusComboBox.Items[1] = LanguageOper.ReadValue(section, "normal");
			mainControlStatusComboBox.Items[2] = LanguageOper.ReadValue(section, "error");
			mainControlStatusComboBox.Items[3] = LanguageOper.ReadValue(section, "detectValue");
			mainControlConnectedComboBox.Items[0] = LanguageOper.ReadValue(section, "unConnected");
			mainControlConnectedComboBox.Items[1] = LanguageOper.ReadValue(section, "connect.0");
			mainControlConnectedComboBox.Items[2] = LanguageOper.ReadValue(section, "connect.1");
			mainControlConnectedComboBox.Items[3] = LanguageOper.ReadValue(section, "connect.2");
			mainControlConnectedComboBox.Items[4] = LanguageOper.ReadValue(section, "detectValue");

			// 界面控件文字
			devInfoGroupBox.Text = LanguageOper.ReadValue(section, "devInfoGroupBox.Text");
			getChainJsonButton.Text = LanguageOper.ReadValue(section, "getChainJsonButton.Text");
			subTestGroupBox.Text = LanguageOper.ReadValue(section, "subTestGroupBox.Text");
			testSubControlButton.Text = LanguageOper.ReadValue(section, "testSubControlButton.Text");
			autoSendSubGroupBox.Text = LanguageOper.ReadValue(section, "autoSendSubGroupBox.Text");
			subFileTipLabel.Text = LanguageOper.ReadValue(section, "subFileTipLabel.Text");
			selectSub4SendButton.Text = LanguageOper.ReadValue(section, "selectSub4SendButton.Text");
			if (autoSendSubEnable == true)
			{
				sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Stop");
			}
			else
			{
				sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Start");
			}
			rdmTestButton.Text = LanguageOper.ReadValue(section, "rdmTestButton.Text");
			dmxConfigButton.Text = LanguageOper.ReadValue(section, "dmxConfigButton.Text");
			lampMcuUpdateButton.Text = LanguageOper.ReadValue(section, "lampMcuUpdateButton.Text");
			controlMcuUpdateButton.Text = LanguageOper.ReadValue(section, "controlMcuUpdateButton.Text");
			gridConfigButton.Text = LanguageOper.ReadValue(section, "gridConfigButton.Text");
			mainControlStatusTipLabel.Text = LanguageOper.ReadValue(section, "mainControlStatusTipLabel.Text");
			mainControlDviTipLabel.Text = LanguageOper.ReadValue(section, "mainControlDviTipLabel.Text");
			languageTipLabel.Text = LanguageOper.ReadValue(section, "languageTipLabel.Text");
            UIDSetButton.Text = LanguageOper.ReadValue(section, "UIDSetButton.Text");
            AmpMcuUpdateButton.Text = LanguageOper.ReadValue(section, "AmpMcuUpdateButton.Text");
            btnLampSet.Text = LanguageOper.ReadValue(section, "btnLampSet.Text");

			if (LanguageOper.LocalLanguage != LanguageEnum.EN)
			{
				mainControlStatusTipLabel.Location = new Point(208, 166);
				mainControlDviTipLabel.Location = new Point(202, 196);
			}
			else
			{
				mainControlStatusTipLabel.Location = new Point(185, 166);
				mainControlDviTipLabel.Location = new Point(172, 196);
			}

			languageChangeEnable = false;

			if (LanguageOper.LocalLanguage == LanguageEnum.CHS)
			{
				languageComboBox.SelectedIndex = 0;
			}
			else if (LanguageOper.LocalLanguage == LanguageEnum.EN)
			{
				languageComboBox.SelectedIndex = 1;
			}
			if (LanguageOper.LocalLanguage == LanguageEnum.CHT)
			{
				languageComboBox.SelectedIndex = 2;
			}

			languageChangeEnable = true;

			#endregion

            #region 快速设置
            btnChipCurrent.Text = LanguageOper.ReadValue(section, "btnChipCurrent.Text");
            btnChipConfig.Text = LanguageOper.ReadValue(section, "btnChipConfig.Text");
            btnSelfChan.Text = LanguageOper.ReadValue(section, "btnSelfChan.Text");
            #endregion

            #region 高级设置
            // 系统配置文件
            contextMenuStrip_Sys.Items[0].Text = LanguageOper.ReadValue(section, "contextSys.ItemsText.0");
            contextMenuStrip_Sys.Items[1].Text = LanguageOper.ReadValue(section, "contextSys.ItemsText.1");
            contextMenuStrip_Sys.Items[2].Text = LanguageOper.ReadValue(section, "contextSys.ItemsText.2");
            sysConfigGroupBox.Text = LanguageOper.ReadValue(section, "sysConfigGroupBox.Text");
            sysConfigButton.Text = LanguageOper.ReadValue(section, "sysConfigButton.Text");

            // 通讯模式
            socketConfigGroupBox.Text = LanguageOper.ReadValue(section, "socketConfigGroupBox.Text");
            useSocketCheckBox.Text = LanguageOper.ReadValue(section, "useSocketCheckBox.Text");
            socketSyncRadioButton.Text = LanguageOper.ReadValue(section, "socketSyncRadioButton.Text");
            socketAsynRadioButton.Text = LanguageOper.ReadValue(section, "socketAsynRadioButton.Text");
            grpUseWinpcap.Text = LanguageOper.ReadValue(section, "grpUseWinpcap.Text");
            grpNetSet.Text = LanguageOper.ReadValue(section, "grpNetSet.Text");
            btnApplyNetSet.Text = LanguageOper.ReadValue(section, "btnApplyNetSet.Text");

            // 分控序号配置
            grpSubIndex.Text = LanguageOper.ReadValue(section, "grpSubIndex.Text");
            btnSubIndex.Text = LanguageOper.ReadValue(section, "btnSubIndex.Text");
            SetArtUnvButton.Text = LanguageOper.ReadValue(section, "SetArtUnvButton.Text");

            // 多路交换机
            switchGroupBox.Text = LanguageOper.ReadValue(section, "switchGroupBox.Text");
            switchEnableCheckBox.Text = LanguageOper.ReadValue(section, "switchEnableCheckBox.Text");
            switchConfigButton.Text = LanguageOper.ReadValue(section, "switchConfigButton.Text");

            // 在线升级
            subUpdateGroupBox.Text = LanguageOper.ReadValue(section, "subUpdateGroupBox.Text");
            subUpdateButton.Text = LanguageOper.ReadValue(section, "subUpdateButton.Text");
            #endregion

            #region 解码器设置

            #endregion

            #region DVI设置

            #endregion
        }

		// 设置当前活跃的数据通路
		public void setActivePath(ActivePath activePath)
		{
			this.activePath = activePath;
		}

		#region 在线检测结果显示

		// 在线结果显示 - 分控详细信息
		private void subDetailButton_Click(object sender, EventArgs e)
		{
			this.addForm("Form_SubDetail", formSubDetail);
			formSubDetail.setLanguageText();
			formSubDetail.ShowDialog();
			this.removeForm("Form_SubDetail");
		}

		// 根据 mainControl 中的信息刷新树
		private void updateMainTree(MainControl mainControl, List<ControlNode> controlNodeList)
		{
			if (formSubDetail != null && formSubDetail.Visible == true)
			{
				formSubDetail.BeginInvoke(formSubDetail.updateSubDetailInfoDelegate, controlNodeList);
			}

			if (refreshMainTreeEnable == false)
			{
				return;
			}

            //更新灯具数量
            if (lampDetectType == DetectType.ArtNet) {
                if (mainControl != null) {
                    foreach (MainPort mainPort in mainControl.MainPortList) {
                        foreach (SubControlChain subControlChain in mainPort.SubControlChainList) {
                            foreach (SubControl subControl in subControlChain.SubControlList) {
                                int sub_no = subControl.DeviceSerNum;
                                int universe_now;
                                int lll = 0;

                                for (int iii = 0; iii < 8; iii++) {
                                    universe_now = sub_no * 8 + iii;
                                    if (baseCoreNet.ArtDevList_uu[universe_now].UIDList != null)
                                        lll = lll + baseCoreNet.ArtDevList_uu[universe_now].UIDList.Count();
                                }
                                subControl.TotalLampNum = lll;

                                int ppp = 0;
                                foreach (SubPort subPort in subControl.SubPortList) {
                                    if (ppp < 8) {
                                        universe_now = sub_no * 8 + ppp;
                                        if (baseCoreNet.ArtDevList_uu[universe_now].UIDList != null)
                                            subPort.TotalLampNum = baseCoreNet.ArtDevList_uu[universe_now].UIDList.Count();
                                    }
                                    ppp = ppp + 1;
                                }
                            }
                        }
                    }
                }
            }

			if (lastMainControl == null || mainTreeGridView.Nodes.Count == 0)
			{
				refreshMainTree_Total(mainControl);
			}
			// 非首次刷新
			else
			{
				// 统计信息
				if (mainControl != null && lastMainControl != null)
				{
					lastMainControl.calcMainPortTotalInfo();
					mainControl.calcMainPortTotalInfo();
				}

				// 全量刷新
				if (mainControl != null && lastMainControl != null && lastMainControl.TotalSubControlNum != mainControl.TotalSubControlNum)
				{
					refreshMainTree_Total(mainControl);
				}
				// 增量刷新
				else
				{
					refreshMainTree_Part(mainControl);
				}
			}
			
			// 更新保存的 lastMainControl
			lastMainControl = mainControl;
		}

		// 根据 mainControl 中的信息刷新树 - 全量刷新
		private void refreshMainTree_Total(MainControl mainControl)
		{
			if (mainControl == null)
			{
				mainTreeGridView.Nodes.Clear();
				if (LanguageOper.available == true)
				{
					string info0 = LanguageOper.ReadValue(section, "noDevInfo.0");
					string info1 = LanguageOper.ReadValue(section, "noDevInfo.1");
					mainTreeGridView.Nodes.Add(info0, info1);
				}
				else
				{
					mainTreeGridView.Nodes.Add("无", "当前未检测到控制器");
				}
				return;
			}

			int mainControlIndex = 0;
			int mainPortIndex = 0;
			int subControlChainIndex = 0;
			int subControlIndex = 0;
			int equControlIndex = 0;
			int subPortIndex = 0;
			int lampIndex = 0;
			int channelIndex = 0;

            mainTreeGridView.Nodes.Clear();

			// Level_0 添加主控节点
			mainControlIndex = mainControl.index;
			TreeGridNode mainControlNode = mainTreeGridView.Nodes.Add(mainControl.name + " " + mainControlIndex, mainControl.tipMessage, (int)mainControl.deviceType, mainTreeRefreshNum);
			mainControlNode.Height = nodeRowHeight;
			// Level_1 添加主控端口节点
			mainPortIndex = 0;
			foreach (MainPort mainPort in mainControl.MainPortList)
			{
				mainPortIndex++;
				TreeGridNode mainPortNode = null;
				if (mainPort.HideFlag == false)
				{
					mainPortNode = mainControlNode.Nodes.Add(mainPort.name, mainPort.buildTipMessage(), (int)mainPort.deviceType, mainTreeRefreshNum);
					mainPortNode.Height = nodeRowHeight;
				}
				else
				{
					mainPortNode = mainControlNode;	// 直接挂载至上级 mainControlNode 节点
				}
				subControlChainIndex = 0;
				// Level_2 添加分控链路节点（交换机端口）
				foreach (SubControlChain subControlChain in mainPort.SubControlChainList)
				{
					subControlChainIndex++;
					TreeGridNode subControlChainNode = null;
					if (subControlChain.HideFlag == false)
					{
						subControlChainNode = mainPortNode.Nodes.Add(subControlChain.name + " " + subControlChain.index, subControlChain.buildTipMessage(), (int)subControlChain.deviceType, mainTreeRefreshNum);
						subControlChainNode.Height = nodeRowHeight;
					}
					else
					{
						subControlChainNode = mainPortNode;
					}

					// Level_3.2 添加附属设备节点
					equControlIndex = 0;
					int lastAddedEquControlIndex = 0;
					foreach (Equipment equipment in subControlChain.EquControlList)
					{
						equControlIndex++;
						TreeGridNode equControlNode = subControlChainNode.Nodes.Add(equipment.name + " " + equipment.index, equipment.buildTipMessage(), (int)equipment.deviceType, mainTreeRefreshNum);
						equControlNode.Height = nodeRowHeight;
						if (equipment.HasErrorNeedDisp)
						{
							string newName = String.Format("{0} [{1}]", equControlNode.Cells[0].Value.ToString(), equipment.brotherCount);
							equControlNode.Cells[0].Value = newName;
							equControlNode.DefaultCellStyle.ForeColor = Color.Red;
						}
						else
						{
							equControlNode.DefaultCellStyle.ForeColor = Color.Black;
						}
						if (equipment.HasNoContinueMarkNeedDisp)
						{
							equControlNode.Cells[0].Value = equControlNode.Cells[0].Value.ToString() + " *";
						}
						lastAddedEquControlIndex = equipment.index;
					}
					// Level_3.1 添加分控节点
					subControlIndex = 0;
                    int lastAddedSubControlIndex = 0;
					foreach (SubControl subControl in subControlChain.SubControlList)
					{
						subControlIndex++;
                        TreeGridNode subControlNode = subControlChainNode.Nodes.Add(subControl.name + " " + subControl.index, subControl.buildTipMessage(), (int)subControl.deviceType, mainTreeRefreshNum);
						subControlNode.Height = nodeRowHeight;
						if (subControl.HasErrorNeedDisp)
						{
							string newName = String.Format("{0} [{1}]", subControlNode.Cells[0].Value.ToString(), subControl.brotherCount);
							subControlNode.Cells[0].Value = newName;
							subControlNode.DefaultCellStyle.ForeColor = Color.Red;
						}
						else
						{
							subControlNode.DefaultCellStyle.ForeColor = Color.Black;
						}
						if (subControl.HasNoContinueMarkNeedDisp)
						{
							subControlNode.Cells[0].Value = subControlNode.Cells[0].Value.ToString() + " *";
						}
						lastAddedSubControlIndex = subControl.index;
						// Level_4 添加分控端口节点
						subPortIndex = 0;
						foreach (SubPort subPort in subControl.SubPortList)
						{
							subPortIndex++;
                            TreeGridNode subPortNode = null;
                            if (lastLampDetectMode == LampCheckMode.RealTime) {
                                subPortNode = subControlNode.Nodes.Add(subPort.name + " " + subPortIndex, subPort.buildTipMessage(), (int)subPort.deviceType, mainTreeRefreshNum);
                            } else if (lastLampDetectMode == LampCheckMode.UseLwf) {
                                if (subTubeDataList.Count >= subControlIndex) {
                                    var subData = subTubeDataList[subControlIndex - 1];
                                    var portList = subData.PortData;
                                    if (portList.Count >= subPortIndex) {
                                        var portData = portList[subPortIndex - 1];
                                        var num = portData.TubePoint.Count;
                                        subPortNode = subControlNode.Nodes.Add(subPort.name + " " + subPortIndex, subPort.buildTipMessage(num), (int)subPort.deviceType, mainTreeRefreshNum);
                                    }
                                }
                            } else {
                                var baseChain = baseCoreNet.GetBaseArtDevChain();
                                if (baseChain != null) {
                                    var dic = baseChain.DetailList;
                                    var portList = dic[subControlIndex];
                                    if (portList.Count >= subPortIndex) {
                                        var portData = portList[subPortIndex - 1];
                                        var num = portData.DeviceList.Count;
                                        subPortNode = subControlNode.Nodes.Add(subPort.name + " " + subPortIndex, subPort.buildTipMessage(num), (int)subPort.deviceType, mainTreeRefreshNum);
                                    }
                                }
                            }
                            
							subPortNode.Height = nodeRowHeight;
							// Level_5 添加灯具节点
							lampIndex = 0;
							foreach (Lamp lamp in subPort.LampList)
							{
								lampIndex++;
								TreeGridNode lampNode = subPortNode.Nodes.Add(lamp.name + " " + lampIndex, lamp.buildTipMessage(), (int)lamp.deviceType, mainTreeRefreshNum);
								lampNode.Height = nodeRowHeight;
								// Level_6 添加管脚节点
								channelIndex = 0;
								foreach (int channel in lamp.ChannelStateList)
								{
									channelIndex++;
									string s1 = "管脚 " + channelIndex;
									string s2 = (channel == 0 ? " 状态: 正常" : " 状态: 异常");
									if (LanguageOper.available == true)
									{
										s1 = LanguageOper.ReadValue(section, "backShowStr.0") + " " + channelIndex;
										s2 = (channel == 0 ? " " + LanguageOper.ReadValue(section, "backShowStr.1") : " " + LanguageOper.ReadValue(section, "backShowStr.2"));
									}
									TreeGridNode channelNode = lampNode.Nodes.Add(s1, s2);
									channelNode.Height = nodeRowHeight;
									if (channel == 1)	// 异常
									{
										setTreeGridNodeForeColor(channelNode, Color.Red);
									}
								}
							}
						}
					}
					// tmp - 原始位置
				}
			}

			// 默认展开至分控节点
			foreach (TreeGridNode node in mainTreeGridView.Nodes)
			{
				expandNodeByType(node, DeviceType.SubControl);
			}
		}

		// 根据 mainControl 中的信息刷新树 - 增量刷新
		private void refreshMainTree_Part(MainControl mainControl)
		{
			if (mainTreeGridView.Nodes.Count == 0)
			{
				refreshMainTree_Total(mainControl);
			}

			if (mainControl == null)
			{
				mainTreeGridView.Nodes.Clear();
				if (LanguageOper.available == true)
				{
					string info0 = LanguageOper.ReadValue(section, "noDevInfo.0");
					string info1 = LanguageOper.ReadValue(section, "noDevInfo.1");
					mainTreeGridView.Nodes.Add(info0, info1);
				}
				else
				{
					mainTreeGridView.Nodes.Add("无", "当前未检测到控制器");
				}
				return;
			}

			bool useSwitch = baseCoreNet.getUseSwitch();

			bool reachMaxPacketNum = false;

			int mainControlIndex = 0;
			int mainPortIndex = 0;
			int subControlChainIndex = 0;
			int subControlIndex = 0;
			int equControlIndex = 0;
			int subPortIndex = 0;
			int lampIndex = 0;
			int channelIndex = 0;
			int mainPortNodeHideNum = 0;
			int subControlChainNodeHideNum = 0;

			mainTreeRefreshNum++;

			// Level_0 刷新主控节点
			/***************************************************************************************/
			mainControlIndex = mainControl.index;
			TreeGridNode mainControlNode = mainTreeGridView.Nodes[0];
			mainControlNode.Cells[0].Value = mainControl.name + " " + mainControlIndex;
			mainControlNode.Cells[1].Value = mainControl.tipMessage;
			mainControlNode.Cells[2].Value = (int)mainControl.deviceType;
			mainControlNode.Cells[3].Value = mainTreeRefreshNum;
			// Level_1 刷新主控端口节点
			/***************************************************************************************/
			mainPortIndex = 0;
			mainPortNodeHideNum = 0;
			foreach (MainPort mainPort in mainControl.MainPortList)
			{
				mainPortIndex++;
				if (mainPortIndex > mainControlNode.Nodes.Count)
				{
					// 存在新的主控端口, 需添加
					addMainPortNode(mainControlNode, mainPort, mainPortIndex);
				}
				else
				{
					// 增量刷新主控端口信息
					TreeGridNode mainPortNode = null;
					if (mainPort.HideFlag == false)
					{
						mainPortNode = mainControlNode.Nodes[mainPortIndex - 1];
						mainPortNode.Cells[0].Value = mainPort.name;
                        mainPortNode.Cells[1].Value = mainPort.buildTipMessage();
                        
						mainPortNode.Cells[2].Value = (int)mainPort.deviceType;
						mainPortNode.Cells[3].Value = mainTreeRefreshNum;
					}
					else
					{
						mainPortNode = mainControlNode;
						mainPortNodeHideNum++;
					}
					// Level_2 刷新分控链路节点
					/*******************************************************************************/
					subControlChainIndex = 0;
					subControlChainNodeHideNum = 0;
					foreach (SubControlChain subControlChain in mainPort.SubControlChainList)
					{
						subControlChainIndex++;
						if (subControlChainIndex > mainPortNode.Nodes.Count && subControlChain.HideFlag == false)
						{
							// 存在新的分控链路, 需添加
							addSubControlChainNode(mainPortNode, subControlChain, subControlChain.index);
						}
						else
						{
							// 增量刷新分控链路信息
							TreeGridNode subControlChainNode = null;
							if (subControlChain.HideFlag == false)
							{
								subControlChainNode = mainPortNode.Nodes[subControlChainIndex - 1];
								subControlChainNode.Cells[0].Value = subControlChain.name + " " + subControlChain.index;
								subControlChainNode.Cells[1].Value = subControlChain.buildTipMessage();
								subControlChainNode.Cells[2].Value = (int)subControlChain.deviceType;
								subControlChainNode.Cells[3].Value = mainTreeRefreshNum;
							}
							else
							{
								subControlChainNode = mainPortNode;
								subControlChainNodeHideNum++;
							}

							// Level_3.2 刷新附属设备节点
							/*******************************************************************************/
							equControlIndex = 0;
							foreach (Equipment equipment in subControlChain.EquControlList)
							{
								equControlIndex++;
								if (equControlIndex > subControlChainNode.Nodes.Count)
								{
									// 存在新的附属设备, 需添加
									addEquControlNode(subControlChainNode, equipment, equipment.index);
								}
								else
								{
									// 增量刷新附属设备信息
									TreeGridNode equControlNode = subControlChainNode.Nodes[equControlIndex - 1];
									int preNodeIndex = equControlIndex - 1 < 0 ? 0 : equControlIndex - 1;
									TreeGridNode preControlNode = subControlChainNode.Nodes[preNodeIndex];
									equControlNode.Cells[0].Value = equipment.name + " " + equipment.index;
									equControlNode.Cells[1].Value = equipment.buildTipMessage();
									equControlNode.Cells[2].Value = (int)equipment.deviceType;
									equControlNode.Cells[3].Value = mainTreeRefreshNum;
									if (equipment.HasErrorNeedDisp)
									{
										string newName = String.Format("{0} [{1}]", equControlNode.Cells[0].Value.ToString(), equipment.brotherCount);
										equControlNode.Cells[0].Value = newName;
										equControlNode.DefaultCellStyle.ForeColor = Color.Red;
									}
									else
									{
										equControlNode.DefaultCellStyle.ForeColor = Color.Black;
									}
									if (equipment.HasNoContinueMarkNeedDisp)
									{
										equControlNode.Cells[0].Value = equControlNode.Cells[0].Value.ToString() + " *";
									}
								}
							}
							/*******************************************************************************/

							// Level_3.1 刷新分控节点
							/*******************************************************************************/
                            subControlIndex = 0;
							foreach (SubControl subControl in subControlChain.SubControlList)
							{
								subControlIndex++;
                                if (subControlIndex + equControlIndex > subControlChainNode.Nodes.Count)
								{
									// 存在新的分控, 需添加
									addSubControlNode(subControlChainNode, subControl, subControl.index);
								}
								else
								{
									// 增量刷新分控信息
									TreeGridNode subControlNode = subControlChainNode.Nodes[subControlIndex + equControlIndex - 1];
									int preNodeIndex = subControlIndex + equControlIndex - 1 < 0 ? 0 : subControlIndex + equControlIndex - 1;
									TreeGridNode preControlNode = subControlChainNode.Nodes[preNodeIndex];
									subControlNode.Cells[0].Value = subControl.name + " " + subControl.index;
									subControlNode.Cells[1].Value = subControl.buildTipMessage();
									if (subControl.ReachMaxPacketNum == true)
									{
										reachMaxPacketNum = true;
									}
									subControlNode.Cells[2].Value = (int)subControl.deviceType;
									subControlNode.Cells[3].Value = mainTreeRefreshNum;
									if (subControl.HasErrorNeedDisp)
									{
										string newName = String.Format("{0} [{1}]", subControlNode.Cells[0].Value.ToString(), subControl.brotherCount);
										subControlNode.Cells[0].Value = newName;
										subControlNode.DefaultCellStyle.ForeColor = Color.Red;
									}
									else
									{
										subControlNode.DefaultCellStyle.ForeColor = Color.Black;
									}
									if (subControl.HasNoContinueMarkNeedDisp)
									{
										subControlNode.Cells[0].Value = subControlNode.Cells[0].Value.ToString() + " *";
									}
									// Level_4 刷新分控端口节点
									/*******************************************************************************/
									subPortIndex = 0;
									foreach (SubPort subPort in subControl.SubPortList)
									{
										subPortIndex++;
										if (subPortIndex > subControlNode.Nodes.Count)
										{
											// 存在新的分控端口, 需添加
											addSubPortNode(subControlNode, subPort, subPortIndex);
										}
										else
										{
											// 增量刷新分控端口信息
											TreeGridNode subPortNode = subControlNode.Nodes[subPortIndex - 1];
											subPortNode.Cells[0].Value = subPort.name + " " + subPortIndex;
                                            subPortNode.Cells[1].Value = subPort.buildTipMessage();
                                            if (lastLampDetectMode == LampCheckMode.UseLwf) {
                                                if (subTubeDataList.Count >= subControlIndex) {
                                                    var subData = subTubeDataList[subControlIndex - 1];
                                                    var portList = subData.PortData;
                                                    if (portList.Count >= subPortIndex) {
                                                        var portData = portList[subPortIndex - 1];
                                                        var num = portData.TubePoint.Count;
                                                        subPortNode.Cells[1].Value = subPort.buildTipMessage(num);
                                                        if (subPort.TotalLampNum != num || subPort.ErrorLampNum != 0) {
                                                            subPortNode.DefaultCellStyle.ForeColor = Color.Red;
                                                        } else {
                                                            subPortNode.DefaultCellStyle.ForeColor = Color.Black;
                                                        }
                                                    }
                                                }
                                            } else if (lastLampDetectMode == LampCheckMode.UseResult) {
                                                var baseChain = baseCoreNet.GetBaseArtDevChain();
                                                if (baseChain != null) {
                                                    var dic = baseChain.DetailList;
                                                    var portList = dic[subControlIndex];
                                                    if (portList.Count >= subPortIndex) {
                                                        var portData = portList[subPortIndex - 1];
                                                        var num = portData.DeviceList.Count;
                                                        subPortNode.Cells[1].Value = subPort.buildTipMessage(num);
                                                        if (subPort.TotalLampNum != num || subPort.ErrorLampNum != 0) {
                                                            subPortNode.DefaultCellStyle.ForeColor = Color.Red;
                                                        } else {
                                                            subPortNode.DefaultCellStyle.ForeColor = Color.Black;
                                                        }
                                                    }
                                                }
                                            }
                                            
											subPortNode.Cells[2].Value = (int)subPort.deviceType;
											subPortNode.Cells[3].Value = mainTreeRefreshNum;
											// Level_5 刷新灯具节点
											/*******************************************************************************/
											lampIndex = 0;
											foreach (Lamp lamp in subPort.LampList)
											{
												lampIndex++;
												if (lampIndex > subPortNode.Nodes.Count)
												{
													// 存在新的灯具, 需添加
													addLampNode(subPortNode, lamp, lampIndex);
												}
												else
												{
													// 增量刷新灯具信息
													TreeGridNode lampNode = subPortNode.Nodes[lampIndex - 1];
													lampNode.Cells[0].Value = lamp.name + " " + lampIndex;
													lampNode.Cells[1].Value = lamp.buildTipMessage();
													lampNode.Cells[2].Value = (int)lamp.deviceType;
													lampNode.Cells[3].Value = mainTreeRefreshNum;
													// Level_6 增量刷新管脚节点
													/*******************************************************************************/
													channelIndex = 0;
													foreach (int channel in lamp.ChannelStateList)
													{
														channelIndex++;
														if (channelIndex > lampNode.Nodes.Count)
														{
															;// 存在新的管脚, 需添加 - TODO
														}
														else
														{
															// 增量刷新管脚信息
															TreeGridNode channelNode = lampNode.Nodes[channelIndex - 1];
															string channelStr = "管脚 " + channelIndex;
															string stateStr = (channel == 0 ? " 状态: 正常" : " 状态: 异常");
															if (LanguageOper.available == true)
															{
																channelStr = LanguageOper.ReadValue(section, "backShowStr.0") + " " + channelIndex;
																stateStr = (channel == 0 ? " " + LanguageOper.ReadValue(section, "backShowStr.1") : " " + LanguageOper.ReadValue(section, "backShowStr.2")); ;
															}
															channelNode.Cells[0].Value = channelStr;
															channelNode.Cells[1].Value = stateStr;
															channelNode.Cells[2].Value = DeviceType.Channel;
															channelNode.Cells[3].Value = mainTreeRefreshNum;
														}
													}
													if (lamp.ChannelStateList.Count < lampNode.Nodes.Count)
													{
														// 存在多余的管脚, 需删除
														for (int i = lampNode.Nodes.Count - 1; i >= lamp.ChannelStateList.Count; i--)
														{
															lampNode.Nodes.RemoveAt(i);
														}
													}
													/*******************************************************************************/
												}
											}
											if (subPort.LampList.Count < subPortNode.Nodes.Count)
											{
												// 存在多余的灯具, 需删除
												for (int i = subPortNode.Nodes.Count - 1; i >= subPort.LampList.Count; i--)
												{
													subPortNode.Nodes.RemoveAt(i);
												}
											}
											/*******************************************************************************/
										}
									}
									if (subControl.SubPortList.Count < subControlNode.Nodes.Count)
									{
										// 存在多余的分控端口, 需删除
										for (int i = subControlNode.Nodes.Count - 1; i >= subControl.SubPortList.Count; i--)
										{
											subControlNode.Nodes.RemoveAt(i);
										}
									}
									/*******************************************************************************/
								}
							}
							if (subControlChain.SubControlList.Count < subControlChainNode.Nodes.Count - subControlChain.EquControlList.Count)
							{
								// 存在多余的分控, 需删除
								for (int i = subControlChainNode.Nodes.Count - 1; i >= subControlChain.SubControlList.Count; i--)
								{
									subControlChainNode.Nodes.RemoveAt(i);
								}
							}
							// tmp - 原始位置
						}
					}
					
					if (mainControl.MainControlType == 0)		// 网口主控
					{
						if ((useSwitch == true && mainPort.SubControlChainList.Count < mainPortNode.Nodes.Count) ||
							(useSwitch == false && mainPort.HideFlag == false && mainPort.SubControlChainList.Count < mainPortNode.Nodes.Count))
						{
							// 存在多余的分控链路, 需删除
							for (int i = mainPortNode.Nodes.Count - 1; i >= mainPort.SubControlChainList.Count; i--)
							{
								mainPortNode.Nodes.RemoveAt(i);
							}
						}
					}
					else if (mainControl.MainControlType == 1)	// 串口主控
					{
						if (mainPort.SubControlChainList.Count == 0)
						{
							mainPortNode.Nodes.Clear();
						}
						else
						{
							SubControlChain subControlChain = mainPort.SubControlChainList[0];
							if (subControlChain.SubControlList.Count + subControlChain.EquControlList.Count < mainPortNode.Nodes.Count)
							{
								// 存在多余的分控/附属设备, 需删除
								for (int i = mainPortNode.Nodes.Count - 1; i >= mainPort.SubControlChainList.Count; i--)
								{
									mainPortNode.Nodes.RemoveAt(i);
								}
							}
						}
					}

					/*******************************************************************************/
				}
			}
			if (mainControl.MainPortList.Count < mainControlNode.Nodes.Count)
			{
				// 存在多余的主控端口, 需删除
				for (int i = mainControlNode.Nodes.Count - 1; i >= mainControl.MainPortList.Count; i--)
				{
					string s1 = mainControlNode.Nodes[i].Cells[2].Value.ToString();
					string s2 = ((int)DeviceType.MainPort).ToString();
					if (s1.Equals(s2))
					{
						mainControlNode.Nodes.RemoveAt(i);
					}
				}
			}
			/***************************************************************************************/

			if (reachMaxPacketNum == true)
			{
				// 有总包数或错包数达到最大，触发事件，发送全局清零命令包
				ReachMaxPacketNumEvent(null, new EventArgs());
			}
		}

		// 增量刷新 - 添加主控节点
		private void addMainControlNode(MainControl mainControl, int mainControlIndex)
		{
			TreeGridNode mainControlNode = mainTreeGridView.Nodes.Add(mainControl.name + " " + mainControlIndex, mainControl.buildTipMessage(), (int)mainControl.deviceType, mainTreeRefreshNum);
			mainControlNode.Height = nodeRowHeight;
			int mainPortIndex = 0;
			foreach (MainPort mainPort in mainControl.MainPortList)
			{
				mainPortIndex++;
				addMainPortNode(mainControlNode, mainPort, mainPortIndex);
			}
		}

		// 增量刷新 - 添加主控端口节点
		private void addMainPortNode(TreeGridNode mainControlNode, MainPort mainPort, int mainPortIndex)
		{
			TreeGridNode mainPortNode = mainControlNode.Nodes.Add(mainPort.name + " " + mainPortIndex, mainPort.buildTipMessage(), (int)mainPort.deviceType, mainTreeRefreshNum);
			mainPortNode.Height = nodeRowHeight;
			int subControlChainIndex = 0;
			foreach (SubControlChain subControlChain in mainPort.SubControlChainList)
			{
				subControlChainIndex++;
				addSubControlChainNode(mainPortNode, subControlChain, subControlChainIndex);
			}
		}

		// 增量刷新 - 添加分控链路节点
		private void addSubControlChainNode(TreeGridNode mainPortNode, SubControlChain subControlChain, int subControlChainIndex)
		{
			TreeGridNode subControlChainNode = mainPortNode.Nodes.Add(subControlChain.name + " " + subControlChain.index, subControlChain.buildTipMessage(), (int)subControlChain.deviceType, mainTreeRefreshNum);
			subControlChainNode.Height = nodeRowHeight;
			int subControlIndex = 0;
			foreach (SubControl subControl in subControlChain.SubControlList)
			{
				subControlIndex++;
				addSubControlNode(subControlChainNode, subControl, subControl.index);
			}
			subControlChainNode.Expand();
		}

		// 增量刷新 - 添加分控节点
		private void addSubControlNode(TreeGridNode subControlChainNode, SubControl subControl, int subControlIndex)
		{
			TreeGridNode subControlNode = subControlChainNode.Nodes.Add(subControl.name + " " + subControlIndex, subControl.buildTipMessage(), (int)subControl.deviceType, mainTreeRefreshNum);
			if (subControl.HasErrorNeedDisp)
			{
				string newName = String.Format("{0} [{1}]", subControlNode.Cells[0].Value.ToString(), subControl.brotherCount);
				subControlNode.Cells[0].Value = newName;
				subControlNode.DefaultCellStyle.ForeColor = Color.Red;
			}
			else
			{
				subControlNode.DefaultCellStyle.ForeColor = Color.Black;
			}
			if (subControl.HasNoContinueMarkNeedDisp)
			{
				subControlNode.Cells[0].Value = subControlNode.Cells[0].Value.ToString() + " *";
			}
			subControlNode.Height = nodeRowHeight;
			int subPortIndex = 0;
			foreach (SubPort subPort in subControl.SubPortList)
			{
				subPortIndex++;
				addSubPortNode(subControlNode, subPort, subPortIndex);
			}
		}

		// 增量刷新 - 添加附属设备节点
		private void addEquControlNode(TreeGridNode subControlChainNode, Equipment equipment, int equControlIndex)
		{
			TreeGridNode equControlNode = subControlChainNode.Nodes.Add(equipment.name + " " + equControlIndex, equipment.buildTipMessage(), (int)equipment.deviceType, mainTreeRefreshNum);
			if (equipment.HasErrorNeedDisp)
			{
				string newName = String.Format("{0} [{1}]", equControlNode.Cells[0].Value.ToString(), equipment.brotherCount);
				equControlNode.Cells[0].Value = newName;
				equControlNode.DefaultCellStyle.ForeColor = Color.Red;
			}
			else
			{
				equControlNode.DefaultCellStyle.ForeColor = Color.Black;
			}
			if (equipment.HasNoContinueMarkNeedDisp)
			{
				equControlNode.Cells[0].Value = equControlNode.Cells[0].Value.ToString() + " *";
			}
			equControlNode.Height = nodeRowHeight;
		}

		// 增量刷新 - 添加分控端口节点
		private void addSubPortNode(TreeGridNode subControlNode, SubPort subPort, int subPortIndex)
		{
			TreeGridNode subPortNode = subControlNode.Nodes.Add(subPort.name + " " + subPortIndex, subPort.buildTipMessage(), (int)subPort.deviceType, mainTreeRefreshNum);
			subPortNode.Height = nodeRowHeight;
			int lampIndex = 0;
			foreach (Lamp lamp in subPort.LampList)
			{
				addLampNode(subPortNode, lamp, lampIndex);
			}
		}

		// 增量刷新 - 添加灯具节点
		private void addLampNode(TreeGridNode subPortNode, Lamp lamp, int lampIndex)
		{
			TreeGridNode lampNode = subPortNode.Nodes.Add(lamp.name + " " + lampIndex, lamp.buildTipMessage(), (int)lamp.deviceType, mainTreeRefreshNum);
			lampNode.Height = nodeRowHeight;
		}

		// 按照类型展开节点
		private void expandNodeByType(TreeGridNode node, DeviceType type)
		{
			try
			{
				int selfTypeValue = int.Parse(node.Cells[2].Value.ToString());
				if (selfTypeValue < (int)type)
				{
					node.Expand();
					foreach (TreeGridNode childNode in node.Nodes)
					{
						expandNodeByType(childNode, type);
					}
				}
				else
				{
					node.Collapse();
				}
			}
			catch (Exception)
			{
				return;
			}
		}

		// 展开至分控节点
		private void expandToSubButton_Click(object sender, EventArgs e)
		{
			foreach (TreeGridNode mainControlNode in mainTreeGridView.Nodes)
			{
				expandNodeByType(mainControlNode, DeviceType.SubControl);
			}
		}

		// 展开至端口节点
		private void expandToPortButton_Click(object sender, EventArgs e)
		{
			foreach (TreeGridNode mainControlNode in mainTreeGridView.Nodes)
			{
				expandNodeByType(mainControlNode, DeviceType.SubPort);
			}
		}

		// 设置树节点前景色 - 按行设置
		private void setTreeGridNodeForeColor(TreeGridNode node, Color foreColor)
		{
			if (node == null)
			{
				return;
			}

			int cellCount = node.Cells.Count;
			for (int i = 0; i < cellCount; i++)
			{
				node.Cells[i].Style.ForeColor = foreColor;
			}
		}

		// 开始刷新/停止刷新
		private void refreshEnableButton_Click(object sender, EventArgs e)
		{
			if (refreshMainTreeEnable == false)
			{
				refreshMainTreeEnable = true;
				refreshEnableButton.Text = "暂停检测";
				if (LanguageOper.available == true)
				{
					refreshEnableButton.Text = LanguageOper.ReadValue(section, "refreshEnableButton.Text.Stop");
				}
			}
			else if (refreshMainTreeEnable == true)
			{
				refreshMainTreeEnable = false;
				refreshEnableButton.Text = "开始检测";
				if (LanguageOper.available == true)
				{
					refreshEnableButton.Text = LanguageOper.ReadValue(section, "refreshEnableButton.Text.Start");
				}
			}
		}

		#endregion

		#region 灯具巡检

		// 查看灯具详细信息 - 全部分控、全部端口
		private void viewDetailButton_Click(object sender, EventArgs e)
		{
			if (mainTreeGridView.Nodes.Count == 0)
			{
				return;
			}
			else if (mainTreeGridView.Nodes[0].Cells[0].Value.ToString().Equals("无"))
			{
				return;
			}

			//string addrMapFileString = addrMapFileTextBox.Text;

            //// 读取布线文件信息 - lwf 格式 - 用作灯具巡检参考依据
            //if (addrMapFileString != null && addrMapFileString.ToLower().EndsWith(".lwf"))
            //{
            //    string xmlFile = ZqConfig.GetAppPath() + Path.DirectorySeparatorChar + "lwf-xml.tmp";
            //    LwfXmlRead.ReadXmlFormLwf(addrMapFileString, xmlFile);
            //    subTubeDataList = lwfSystemTubeReader.readSystemTubeDataFormXml(xmlFile);
            //    if (File.Exists(xmlFile))
            //    {
            //        File.Delete(xmlFile);
            //    }
            //}
            //// 读取布线文件信息 -  json 格式 - 用作灯具巡检参考依据
            //else if (addrMapFileString != null && addrMapFileString.ToLower().EndsWith(".json"))
            //{
            //    subTubeDataList.Clear();
            //}
            //// 读取布线文件信息 -  dxf 格式 - 用作灯具巡检参考依据
            //else if (addrMapFileString != null && addrMapFileString.ToLower().EndsWith(".dxf"))
            //{
            //    subTubeDataList.Clear();
            //}

			Form_DetectDetail detectDetailForm = new Form_DetectDetail(showTestTabEnable);
			detectDetailForm.setParentForm(this);
			detectDetailForm.setBaseCoreNet(baseCoreNet, baseCoreCom, activePath);
			detectDetailForm.setReferSubTubeDataList(subTubeDataList);
            detectDetailForm.setDetectType(lampDetectType);

			int totalSubNum = 0;
			if (activePath == ActivePath.Net)
			{
				totalSubNum = baseCoreNet.getSubControlNum();
			}
			else if (activePath == ActivePath.Com)
			{
                if (baseCoreCom != null) {
                    ComMainControl mainControl = baseCoreCom.getActiveComMainControl();
                    if (mainControl != null) {
                        totalSubNum = baseCoreCom.getSubControlNum(mainControl.index);
                    }
                }
			}

			// 设置灯具巡检参数
			detectDetailForm.setCheckParameter(totalSubNum, -1, 0, 0);

			this.addForm("Form_DetectDetail", detectDetailForm);
			detectDetailForm.setLanguageText();
			detectDetailForm.ShowDialog();
			this.removeForm("Form_DetectDetail");

            setAutoDetectEnableRDM();
		}

		// 右键菜单项 - 显示详细信息
		private void mainTreeGridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
		{
			if (e.RowIndex < 0)
			{
				return;
			}

			if (e.Button == MouseButtons.Right && e.RowIndex > -1 && e.ColumnIndex > -1)
			{
				mainTreeGridView.CurrentRow.Selected = false;
				mainTreeGridView.Rows[e.RowIndex].Selected = true;
				mainTreeGridView.CurrentCell = mainTreeGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
				int typeValue = int.Parse(mainTreeGridView.Rows[e.RowIndex].Cells[2].Value.ToString());
				if(typeValue != (int)DeviceType.Equipment)
				{
					this.contextMenuStrip_DetectDetail = new System.Windows.Forms.ContextMenuStrip();
					string fontName = this.Font.Name;
					contextMenuStrip_DetectDetail.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
					AddContextMenu("查看灯具信息", contextMenuStrip_DetectDetail.Items, showDetectDetail);
					if (LanguageOper.available == true)
					{
						contextMenuStrip_DetectDetail.Items[0].Text = LanguageOper.ReadValue(section, "contextDetectDetail.ItemsText.0");
					}
					contextMenuStrip_DetectDetail.Show(MousePosition.X, MousePosition.Y);
				}
				this.BringToFront();
			}
		}

		// 启动灯具巡检 - 显示详细信息
		private void showDetectDetail(object sender, EventArgs e)
		{
			if (mainTreeGridView.Nodes.Count == 0)
			{
				return;
			}
			else if (mainTreeGridView.Nodes[0].Cells[0].Value.ToString().Equals("无"))
			{
				return;
			}

            //string addrMapFileString = addrMapFileTextBox.Text;

            //// 读取布线文件信息 - lwf 格式 - 用作灯具巡检参考依据
            //if (addrMapFileString != null && addrMapFileString.ToLower().EndsWith(".lwf"))
            //{
            //    fillSubTubDataList(addrMapFileString);
            //}

			Form_DetectDetail detectDetailForm = new Form_DetectDetail(showTestTabEnable);
			detectDetailForm.setParentForm(this);
			detectDetailForm.setBaseCoreNet(baseCoreNet, baseCoreCom, activePath);
			detectDetailForm.setReferSubTubeDataList(subTubeDataList);
            detectDetailForm.setDetectType(lampDetectType);

			// 分控端口级巡检
			if (mainTreeGridView.CurrentRow.Cells[2].Value.ToString().Equals(((int)DeviceType.SubPort).ToString()))
			{
				try
				{
					string subPortText = mainTreeGridView.CurrentRow.Cells[0].Value.ToString();
					int portIndex = int.Parse(subPortText.Split()[1]);

					TreeGridNode subCtrlNode = mainTreeGridView.CurrentRow.Parent;
					string subControlText = subCtrlNode.Cells[0].Value.ToString();
					int subIndex = int.Parse(subControlText.Split()[1]);

					// 不启用交换机: 网口主控不显示 "分端口级"、"链路级"; 启用交换机: 网口主控不显示 "分端口级"
					TreeGridNode mainCtrlNode = subCtrlNode.Parent;
					int nodeCount = mainCtrlNode.Nodes.Count;
					string subText = mainCtrlNode.Nodes[nodeCount - 1].Cells[0].Value.ToString().Replace("*", "").Trim();
					int totalSubNum = int.Parse(subText.Split()[1]);

					// 设置灯具巡检参数
					detectDetailForm.setCheckParameter(totalSubNum, -1, subIndex, portIndex);
				}
				catch (Exception)
				{
					string msg = "灯具巡检参数解析错误！";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.23");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
			}
			// 分控级巡检
			else if (mainTreeGridView.CurrentRow.Cells[2].Value.ToString().Equals(((int)DeviceType.SubControl).ToString()))
			{
				try
				{
					string subControlText = mainTreeGridView.CurrentRow.Cells[0].Value.ToString();
					int subIndex = int.Parse(subControlText.Split()[1]);

					// 不启用交换机: 网口主控不显示 "分端口级"、"链路级"; 启用交换机: 网口主控不显示 "分端口级"
					TreeGridNode mainCtrlNode = mainTreeGridView.CurrentRow.Parent;
					int nodeCount = mainCtrlNode.Nodes.Count;
					string subText = mainCtrlNode.Nodes[nodeCount - 1].Cells[0].Value.ToString().Replace("*", "").Trim();
					int totalSubNum = int.Parse(subText.Split()[1]);

					// 设置灯具巡检参数
					detectDetailForm.setCheckParameter(totalSubNum, -1, subIndex, 0);
				}
				catch (Exception)
				{
					string msg = "灯具巡检参数解析错误！";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.23");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
			}
			// 网口主控级巡检
			else if (mainTreeGridView.CurrentRow.Cells[2].Value.ToString().Equals(((int)DeviceType.MainControl).ToString()))
			{
				try
				{
					// 网口主控不显示 "分端口级"、"链路级"
					int totalSubNum = mainTreeGridView.CurrentRow.Nodes.Count;

					// 设置灯具巡检参数
					detectDetailForm.setCheckParameter(totalSubNum, -1, 0, 0);
				}
				catch (Exception)
				{
					string msg = "灯具巡检参数解析错误！";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.23");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
			}
			// 网口主控交换机端口级巡检
			else if (mainTreeGridView.CurrentRow.Cells[2].Value.ToString().Equals(((int)DeviceType.SubControlChain).ToString()))
			{
				string msg = "暂不支持交换机端口级别的灯具巡检";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.24");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				return;
			}
			// 串口主控端口级巡检
			else if (mainTreeGridView.CurrentRow.Cells[2].Value.ToString().Equals(((int)DeviceType.MainPort).ToString()))
			{
				try
				{
					// 设置灯具巡检参数
					int totalSubNum = mainTreeGridView.CurrentRow.Nodes.Count;
					detectDetailForm.setCheckParameter(totalSubNum, -1, 0, 0);
				}
				catch (Exception)
				{
					string msg = "灯具巡检参数解析错误！";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.23");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
			}

			try
			{
				this.addForm("Form_DetectDetail", detectDetailForm);
				detectDetailForm.setLanguageText();
				detectDetailForm.ShowDialog();
				this.removeForm("Form_DetectDetail");
			}
			catch (Exception ex)
			{
				MessageBoxEx.Show(this, ex.Message + ex.StackTrace, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

        private void fillSubTubDataList(string addrMapFileString) {
            string xmlFile = ZqConfig.GetAppPath() + Path.DirectorySeparatorChar + "lwf-xml.tmp";
            LwfXmlRead.ReadXmlFormLwf(addrMapFileString, xmlFile);
            subTubeDataList = lwfSystemTubeReader.readSystemTubeDataFormXml(xmlFile);
            if (File.Exists(xmlFile)) {
                File.Delete(xmlFile);
            }
        }

		#endregion

		#region Tab 系统配置 - 业务逻辑

		// 系统配置 - 备份/恢复文件 - 显示菜单
		private void sysConfigButton_Click(object sender, EventArgs e)
		{
			// 设置 menu 显示位置
			this.contextMenuStrip_Sys = new System.Windows.Forms.ContextMenuStrip();
			string fontName = this.Font.Name;
			contextMenuStrip_Sys.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
			AddContextMenu("打开", contextMenuStrip_Sys.Items, openSysBackFile_Click);
			AddContextMenu("保存", contextMenuStrip_Sys.Items, saveSysBackFile_Click);
			AddContextMenu("另存为", contextMenuStrip_Sys.Items, saveOtherSysBackFile_Click);
			if (LanguageOper.available == true)
			{
				contextMenuStrip_Sys.Items[0].Text = LanguageOper.ReadValue(section, "contextSys.ItemsText.0");
				contextMenuStrip_Sys.Items[1].Text = LanguageOper.ReadValue(section, "contextSys.ItemsText.1");
				contextMenuStrip_Sys.Items[2].Text = LanguageOper.ReadValue(section, "contextSys.ItemsText.2");
			}
			Point pt = new Point(sysConfigButton.Location.X, sysConfigButton.Location.Y + sysConfigButton.Height);
			this.contextMenuStrip_Sys.Show(this.sysConfigGroupBox, pt);
			this.BringToFront();
		}

		// 系统配置 - 备份/恢复文件 - 打开
		private void openSysBackFile_Click(object sender, EventArgs e)
		{
			OpenFileDialog o = new OpenFileDialog();
			o.Filter = "Dat Files(*.dat)|*.dat";
			o.Multiselect = false;
			if (Directory.Exists(lastPath_SysBackFile))
			{
				o.InitialDirectory = lastPath_SysBackFile;
			}
			else
			{
				o.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
			}
			DialogResult dr = o.ShowDialog();
			if (dr == DialogResult.OK)
			{
				bool res = readSysBackFile(o.FileName);
				if (res == true)
				{
					lastPath_SysBackFile = (new FileInfo(o.FileName)).DirectoryName;

					sysConfigTextBox.Text = o.FileName;
					sysConfigTextBox.SelectionStart = sysConfigTextBox.Text.Length;
					sysConfigTextBox.ScrollToCaret();

					contextMenuStrip_Sys.Items[1].Enabled = true;
					contextMenuStrip_Sys.Items[2].Enabled = true;
				}
				else
				{
					return;
				}
			}
		}

		// 系统配置 - 备份/恢复文件 - 保存
		private void saveSysBackFile_Click(object sender, EventArgs e)
		{
			if (sysConfigTextBox.Text.Equals(""))
			{
				return;
			}
			else
			{
				saveSysBackFile(sysConfigTextBox.Text.Trim());
				string msg = "系统配置文件保存成功";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.7");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

		// 系统配置 - 备份/恢复文件 - 另存为
		private void saveOtherSysBackFile_Click(object sender, EventArgs e)
		{
			SaveFileDialog s = new SaveFileDialog();
			s.Filter = "Dat Files(*.dat)|*.dat";
			s.FilterIndex = 1;
			s.FileName = sysConfigTextBox.Text;
			if (s.ShowDialog() == DialogResult.OK)
			{
				saveSysBackFile(s.FileName);
				sysConfigTextBox.Text = s.FileName;
				sysConfigTextBox.SelectionStart = sysConfigTextBox.Text.Length;
				sysConfigTextBox.ScrollToCaret();
				string msg = "系统配置文件保存成功";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.7");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

		// 系统配置 - 读取系统配置文件
		private bool readSysBackFile(string filePath)
		{
			BinaryReader reader = null;
			FileStream fs = null;
			try
			{
				fs = new FileStream(filePath, FileMode.Open);
				reader = new BinaryReader(fs);
				byte[] headData = reader.ReadBytes(48);

				// 判断是否为系统配置备份文件
				if (headData[0x0000] != 0x53 || headData[0x0001] != 0x42 || headData[0x0002] != 0x41
					|| headData[0x0003] != 0x43 || headData[0x0004] != 0x4B)
				{
					string msg = "读取系统配置备份文件失败, 文件类型不匹配";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.8");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return false;
				}

				// 摘要起始地址
				int summaryStart = headData[0x0014] << 24 | headData[0x0015] << 16 | headData[0x0016] << 8 | headData[0x0017];

				// 摘要数据长度
				int summaryLength = headData[0x0018] << 24 | headData[0x0019] << 16 | headData[0x001A] << 8 | headData[0x001B];

				// 读取摘要数据
				fs.Seek(summaryStart, SeekOrigin.Begin);
				byte[] summaryDataBytes = reader.ReadBytes(summaryLength);
				string summaryData = System.Text.Encoding.Default.GetString(summaryDataBytes);

				// 解析 Json - 获得内部数据结构（BackInfoSummary）
				BackInfoSummary summary = (BackInfoSummary)JsonConvert.DeserializeObject(summaryData, typeof(BackInfoSummary));

				// 根据摘要解析交换机配置数据 - Json 格式
				if (summary.switchEnable)
				{
					if (summary.switchDataType.ToLower().Equals("json"))
					{
						int startAddr = Convert.ToInt32(summary.switchDataStart.Substring(2), 16);
						int dataLength = summary.switchDataLength;
						fs.Seek(startAddr, SeekOrigin.Begin);
						byte[] switchDataBytes = reader.ReadBytes(dataLength);
						string switchData = System.Text.Encoding.Default.GetString(switchDataBytes);

						StreamWriter writer = new StreamWriter(new FileStream(innerSwitchDataFilePath, FileMode.Create));
						writer.Write(switchData);
						writer.Flush();
						writer.Close();

						// 启用多路交换机
						if (baseCoreNet != null)
						{
							baseCoreNet.readSwitchConfigFileJson(innerSwitchDataFilePath);
							baseCoreNet.setUseSwitch(true);
						}

						switchCheckAction = false;

						switchEnableCheckBox.Checked = true;
						switchConfigButton.Enabled = true;
						switchConfigFileTextBox.Enabled = true;
						switchConfigFileTextBox.Text = useInnerSwitchDataTip;

						switchCheckAction = true;
					}
				}
				else
				{
					// 清除临时文件
					if (File.Exists(innerSwitchDataFilePath))
					{
						try
						{
							File.Delete(innerSwitchDataFilePath);
						}
						catch (Exception)
						{
							;
						}
					}

					// 禁用多路交换机
					if (baseCoreNet != null)
					{
						baseCoreNet.setUseSwitch(false);
					}

					switchCheckAction = true;

					switchEnableCheckBox.Checked = false;
					switchConfigButton.Enabled = false;
					switchConfigFileTextBox.Enabled = false;
					switchConfigFileTextBox.Text = "";

					switchCheckAction = true;
				}

				// 根据摘要解析异形映射配置数据 - lwf/Json/dxf 格式
				if (summary.addrEnable)
				{
					string dataType = summary.addrDataType.ToLower();

					int startAddr = Convert.ToInt32(summary.addrDataStart.Substring(2), 16);
					int dataLength = summary.addrDataLength;
					fs.Seek(startAddr, SeekOrigin.Begin);
					byte[] addrDataBytes = reader.ReadBytes(dataLength);

					// 文本格式
					if (dataType.Equals("json"))
					{
						string addrData = System.Text.Encoding.Default.GetString(addrDataBytes);
						StreamWriter writer = new StreamWriter(new FileStream(innerAddrDataFilePath, FileMode.Create));
						writer.Write(addrData);
						writer.Flush();
						writer.Close();
					}
					// 二进制格式
					else if (dataType.Equals("lwf") || dataType.Equals("dxf"))
					{
						BinaryWriter writer = new BinaryWriter(new FileStream(innerAddrDataFilePath, FileMode.Create));
						writer.Write(addrDataBytes);
						writer.Flush();
						writer.Close();
					}

					// 启用异形地址映射
					addrMapFileType = dataType;
					addrMapFilePath = innerAddrDataFilePath;
					setAddrMapEnable(true);

					addrMapFileTextBox.Text = useInnerAddrDataTip;
					addrMapFileTextBox.SelectionStart = addrMapFileTextBox.Text.Length;
					addrMapFileTextBox.ScrollToCaret();
				}
				else
				{
					// 清除临时文件
					if (File.Exists(innerAddrDataFilePath))
					{
						try
						{
							File.Delete(innerAddrDataFilePath);
						}
						catch (Exception)
						{
							;
						}
					}

					// 禁用异形地址映射
					addrMapFileType = "";
					addrMapFilePath = "";
					setAddrMapEnable(false);

					addrMapFileTextBox.Text = "";
				}

				// 根据摘要解析分控配置数据 - sub 格式

				return true;
			}
			catch (Exception ex)
			{
				MessageBoxEx.Show(this, ex.Message + ex.StackTrace, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				return false;
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
				}
				switchCheckAction = true;
			}
		}

		// 系统配置 - 保存系统配置文件
		private void saveSysBackFile(string filePath)
		{
			BinaryReader switchDataReader = null;
			BinaryReader addrMapDataReader = null;
			try
			{
				// 收集相关信息
				BackInfoSummary summary = new BackInfoSummary();

				// 交换机配置数据
				byte[] switchDataBytes = null;
				if (switchEnableCheckBox.Checked)
				{
					summary.switchEnable = true;						// 交换机启用状态
					summary.switchDataType = "json";					// 交换机数据类型 - 固定为 Json
					if (switchConfigFilePath != null && !switchConfigFilePath.Equals(""))
					{
						FileStream fs = new FileStream(switchConfigFilePath, FileMode.Open);
						switchDataReader = new BinaryReader(fs);
						switchDataBytes = switchDataReader.ReadBytes((int)fs.Length);
						summary.switchDataStart = "0xFFFFFFFF";			// 起始地址 - 在后续代码赋值
						summary.switchDataLength = (int)fs.Length;		// 数据长度
						switchDataReader.Close();
						switchDataReader = null;
					}
				}
				else
				{
					summary.switchEnable = false;						// 交换机启用状态
					summary.switchDataType = "json";					// 交换机数据类型 - 固定为 Json
					summary.switchDataStart = "0xFFFFFFFF";				// 起始地址 - 在后续代码赋值
					summary.switchDataLength = 0;						// 数据长度
				}

				// 异形映射配置数据
				byte[] addrMapDataBytes = null;
				if (baseCoreNet.getAddrMapEnable())
				{
					summary.addrEnable = true;							// 异形映射启用状态
					summary.addrDataType = addrMapFileType;				// 异形映射数据类型 - lwf/json/dxf
					if (addrMapFilePath != null && !addrMapFilePath.Equals(""))
					{
						FileStream fs = new FileStream(addrMapFilePath, FileMode.Open);
						addrMapDataReader = new BinaryReader(fs);
						addrMapDataBytes = addrMapDataReader.ReadBytes((int)fs.Length);
						summary.addrDataStart = "0xFFFFFFFF";			// 起始地址 - 在后续代码赋值
						summary.addrDataLength = (int)fs.Length;		// 数据长度
						addrMapDataReader.Close();
						addrMapDataReader = null;
					}
				}
				else
				{
					summary.addrEnable = false;
					summary.addrDataType = "lwf";						// 异形映射数据类型 - lwf/json/dxf
					summary.addrDataStart = "0xFFFFFFFF";				// 起始地址 - 在后续代码赋值
					summary.addrDataLength = 0;							// 数据长度
				}

				// 分控配置数据
				byte[] subConfigData = rvCardL9Config.GetSubData();		// 当前的分控配置数据
				summary.subEnable = true;								// 分控配置启用状态
				summary.subDataNum = 1;									// 分控配置区数量
				summary.subDataStart = "0xFFFFFFFF";					// 起始地址 - 在后续代码赋值
				summary.subDataLength = 128 * 1024 * summary.subDataNum;// 数据长度 = 128K * subDataNum

				// 预生成 summaryData, 获取长度用于修改起始地址
				string summaryData = JsonConvert.SerializeObject(summary, Newtonsoft.Json.Formatting.Indented);
				int summaryDataLength = System.Text.Encoding.Default.GetBytes(summaryData).Length;

				int switchDataPosition = 48 + summaryDataLength;
				int addrDataPosition = switchDataPosition + (switchDataBytes == null ? 0 : switchDataBytes.Length);
				int subDataPosition = addrDataPosition + (addrMapDataBytes == null ? 0 : addrMapDataBytes.Length);

				// 修正起始地址
				if (summary.switchEnable)
				{
					summary.switchDataStart = Tools.Byte2HexStringWith0x(Tools.int2Byte4SmallEnd(switchDataPosition));
				}
				if (summary.addrEnable)
				{
					summary.addrDataStart = Tools.Byte2HexStringWith0x(Tools.int2Byte4SmallEnd(addrDataPosition));
				}
				if (summary.subEnable)
				{
					summary.subDataStart = Tools.Byte2HexStringWith0x(Tools.int2Byte4SmallEnd(subDataPosition));
				}

				// 生成摘要区数据
				summaryData = JsonConvert.SerializeObject(summary, Newtonsoft.Json.Formatting.Indented);
				if (summaryDataLength != System.Text.Encoding.Default.GetBytes(summaryData).Length)
				{
					MessageBoxEx.Show(this, "Error, SummaryDataLength Changed!", tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return;
				}

				/***************************************************************************************************/

				// 全部待写入的数据
				byte[] totalData = new byte[subDataPosition + 128 * 1024 * summary.subDataNum];

				// 文件头 - 文件标识及版本
				totalData[0x0000] = 0x53;		// 'S'
				totalData[0x0001] = 0x42;		// 'B'
				totalData[0x0002] = 0x41;		// 'A'
				totalData[0x0003] = 0x43;		// 'C'
				totalData[0x0004] = 0x4B;		// 'K'
				totalData[0x0005] = 0x01;		// 文件版本 - v1
				// 0x0006 - 0x000F				// 保留

				// 文件总大小
				byte[] totalDataLengthBytes = Tools.int2Byte4BigEnd(totalData.Length);
				totalData[0x0010] = totalDataLengthBytes[3];		// 文件总大小高字节
				totalData[0x0011] = totalDataLengthBytes[2];		// 文件总大小字节2
				totalData[0x0012] = totalDataLengthBytes[1];		// 文件总大小字节1
				totalData[0x0013] = totalDataLengthBytes[0];		// 文件总大小字节0

				// 摘要起始地址
				byte[] summaryDataStartBytes = Tools.int2Byte4BigEnd(48);
				totalData[0x0014] = summaryDataStartBytes[3];		// 摘要起始地址高字节
				totalData[0x0015] = summaryDataStartBytes[2];		// 摘要起始地址字节2
				totalData[0x0016] = summaryDataStartBytes[1];		// 摘要起始地址字节1
				totalData[0x0017] = summaryDataStartBytes[0];		// 摘要起始地址低字节

				// 摘要数据长度
				byte[] summaryDataLengthBytes = Tools.int2Byte4BigEnd(summaryDataLength);
				totalData[0x0018] = summaryDataLengthBytes[3];		// 摘要数据长度高字节
				totalData[0x0019] = summaryDataLengthBytes[2];		// 摘要数据长度字节2
				totalData[0x001A] = summaryDataLengthBytes[1];		// 摘要数据长度字节1
				totalData[0x001B] = summaryDataLengthBytes[0];		// 摘要数据长度低字节

				// 复制摘要区数据
				Array.Copy(System.Text.Encoding.Default.GetBytes(summaryData), 0, totalData, 48, summaryDataLength);

				// 复制交换机配置数据
				if (switchDataBytes != null)
				{
					Array.Copy(switchDataBytes, 0, totalData, switchDataPosition, switchDataBytes.Length);
				}

				// 复制异形映射配置数据
				if (addrMapDataBytes != null)
				{
					Array.Copy(addrMapDataBytes, 0, totalData, addrDataPosition, addrMapDataBytes.Length);
				}

				// 复制分控配置数据
				Array.Copy(subConfigData, 0, totalData, subDataPosition, subConfigData.Length);

				// 计算 CRC 校验并填充
				byte[] crc32Data = Tools.int2Byte4BigEnd(Tools.getCRC32(totalData));
				totalData[0x001C] = crc32Data[3];
				totalData[0x001D] = crc32Data[2];
				totalData[0x001E] = crc32Data[1];
				totalData[0x001F] = crc32Data[0];

				// 写入数据
				BinaryWriter writer = new BinaryWriter(new FileStream(filePath, FileMode.Create));
				writer.Write(totalData);
				writer.Flush();
				writer.Close();
			}
			catch (Exception ex)
			{
				MessageBoxEx.Show(this, ex.Message + ex.StackTrace, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
			finally
			{
				if (switchDataReader != null)
				{
					switchDataReader.Close();
				}
				if (addrMapDataReader != null)
				{
					addrMapDataReader.Close();
				}
			}
		}

		// 系统配置 - 布线文件 - 显示菜单
		private void addrMapButton_Click(object sender, EventArgs e)
		{
			// 设置 menu 显示位置
			this.contextMenuStrip_AddrMap = new System.Windows.Forms.ContextMenuStrip();
			string fontName = this.Font.Name;
			contextMenuStrip_AddrMap.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
			AddContextMenu("打开", contextMenuStrip_AddrMap.Items, openAddrMapFile_Click);
            AddContextMenu("清除", contextMenuStrip_AddrMap.Items, clearAddrMapFile_Click);
            AddContextMenu("文件信息", contextMenuStrip_AddrMap.Items, btnLwfFileInfo_Click);
			if (LanguageOper.available == true)
			{
				contextMenuStrip_AddrMap.Items[0].Text = LanguageOper.ReadValue(section, "contextAddrMap.ItemsText.0");
                contextMenuStrip_AddrMap.Items[1].Text = LanguageOper.ReadValue(section, "contextAddrMap.ItemsText.1");
                contextMenuStrip_AddrMap.Items[2].Text = LanguageOper.ReadValue(section, "readLampParaButton.Text.1");
			}
			Point pt = new Point(addrMapButton.Location.X, addrMapButton.Location.Y + addrMapButton.Height);
			this.contextMenuStrip_AddrMap.Show(this.addrMapGroupBox, pt);
			this.BringToFront();
		}

		// 系统配置 - 布线文件 - 打开
		private void openAddrMapFile_Click(object sender, EventArgs e)
		{
            StartAddrMapPara startPara = new StartAddrMapPara();
            startPara.fileType = "lwf";
            OpenFileDialog o = new OpenFileDialog();
            o.Filter = "Lwf Files(*.lwf)|*.lwf";
            o.FilterIndex = 1;
            o.Multiselect = false;
            if (Directory.Exists(this.lastPath_StartAddrMap_AddrMapFile))
            {
                o.InitialDirectory = this.lastPath_StartAddrMap_AddrMapFile;
            }
            else
            {
                o.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            }
            DialogResult dr = o.ShowDialog();
            if (dr == DialogResult.OK)
            {
                bool res = preReadLwfFile(o.FileName);
                if (!res)
                {
                    string msg = string.Format("布线文件 {0} 格式错误, 请检查", o.FileName);
                    if (LanguageOper.available == true)
                    {
                        msg = string.Format(LanguageOper.ReadValue(section, "msgStr.0"), o.FileName);
                    }

                    MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                else
                {
                    startPara.filePath = o.FileName;
                }
                if (!startPara.filePath.Equals(""))
                {
                    // 参数完整 - 启用异形映射
                    addrMapFileType = startPara.fileType;
                    addrMapFilePath = startPara.filePath;
                    setAddrMapEnable(true);
                }
                else
                {
                    // 参数不完整 - 关闭异形映射
                    setAddrMapEnable(false);
                }
            }
		}

		// 系统配置 - 布线文件 - 另存为
		private void saveOtherAddrMapFile_Click(object sender, EventArgs e)
		{
			if (addrMapFileTextBox.Text.Equals(""))
			{
				string msg = "当前无布线文件";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.9");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				return;
			}

			string filterStr = "";

			if (addrMapFileType.Equals("lwf"))
			{
				filterStr = "Lwf Files(*.lwf)|*.lwf";
			}
			else if (addrMapFileType.Equals("json"))
			{
				filterStr = "Json Files(*.json)|*.json";
			}
			else if (addrMapFileType.Equals("dxf"))
			{
				filterStr = "Dxf Files(*.dxf)|*.dxf";
			}

			SaveFileDialog s = new SaveFileDialog();
			s.Filter = filterStr;
			s.FilterIndex = 1;
			if (s.ShowDialog() == DialogResult.OK)
			{
				if (addrMapFileTextBox.Text.Equals(s.FileName))
				{
					// 同名文件, 无需另存
					string msg = "布线文件保存完成";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.10");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return;
				}

				// 当前配置数据为从系统配置文件中提取的数据
				if (addrMapFileTextBox.Text.Equals(useInnerAddrDataTip))
				{
					// 内部临时文件存在, 直接复制
					if (File.Exists(innerAddrDataFilePath))
					{
						File.Copy(innerAddrDataFilePath, s.FileName, true);
					}
					// 内部临时文件不存在, 从系统配置文件中提取数据
					else
					{
						if (File.Exists(sysConfigTextBox.Text.Trim()))
						{
							saveAddrMapFileFromSysConfFile(sysConfigTextBox.Text.Trim(), s.FileName);
						}
						else
						{
							string msg = string.Format("无法找到系统配置文件 {0}", sysConfigTextBox.Text.Trim());
							if (LanguageOper.available == true)
							{
								msg = string.Format(LanguageOper.ReadValue(section, "msgStr.11"), sysConfigTextBox.Text.Trim());
							}
							MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
						}
					}
				}
				// 当前配置数据由用户指定
				else
				{
					File.Copy(addrMapFileTextBox.Text.Trim(), s.FileName, true);
				}

				addrMapFileTextBox.Text = s.FileName;
				addrMapFileTextBox.SelectionStart = addrMapFileTextBox.Text.Length;
				addrMapFileTextBox.ScrollToCaret();
				setConfigValue(agentIni, "addrMapFilePath", addrMapFileTextBox.Text.Trim());

				string msg1 = "布线文件保存完成";
				if (LanguageOper.available == true)
				{
					msg1 = LanguageOper.ReadValue(section, "msgStr.10");
				}
				MessageBoxEx.Show(this, msg1, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

		// 系统配置 - 布线文件 - 清除
		private void clearAddrMapFile_Click(object sender, EventArgs e)
		{
			if (addrMapFileTextBox.Text.Equals(""))
			{
				return;
			}

			string msg = "此操作不会清除分控中的布线, 清除分控布线请使用 “清除布线” 按钮\n\n确定要清除当前的布线文件吗？";
			if (LanguageOper.available == true)
			{
				msg = LanguageOper.ReadValue(section, "msgStr.12");
			}
			DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

			if (dr == System.Windows.Forms.DialogResult.OK)
			{

				addrMapFileTextBox.Text = "";

				setConfigValue(agentIni, "addrMapFilePath", "");
				setConfigValue(agentIni, "addrMapFileType", "");

				lastPath_StartAddrMap_AddrMapFile = "";

				baseCoreNet.clearDeclareMainControlList();

				mainTreeGridView.Focus();

                setAddrMapEnable(false); // 清除异形文件即为关闭异形映射使能
			}
		}

		// 系统配置 - 布线文件 - 保存布线文件（从系统配置文件中提取数据）
		private void saveAddrMapFileFromSysConfFile(string sysConfigFilePath, string addrMapDataFilePath)
		{
			BinaryReader reader = null;
			FileStream fs = null;
			try
			{
				fs = new FileStream(sysConfigFilePath, FileMode.Open);
				reader = new BinaryReader(fs);
				byte[] headData = reader.ReadBytes(48);

				// 判断是否为系统配置备份文件
				if (headData[0x0000] != 0x53 || headData[0x0001] != 0x42 || headData[0x0002] != 0x41 || headData[0x0003] != 0x43 || headData[0x0004] != 0x4B)
				{
					string msg = "读取系统配置备份文件失败, 文件类型不匹配";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.8");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return;
				}

				// 摘要起始地址
				int summaryStart = headData[0x0014] << 24 | headData[0x0015] << 16 | headData[0x0016] << 8 | headData[0x0017];

				// 摘要数据长度
				int summaryLength = headData[0x0018] << 24 | headData[0x0019] << 16 | headData[0x001A] << 8 | headData[0x001B];

				// 读取摘要数据
				fs.Seek(summaryStart, SeekOrigin.Begin);
				byte[] summaryDataBytes = reader.ReadBytes(summaryLength);
				string summaryData = System.Text.Encoding.Default.GetString(summaryDataBytes);

				// 解析 Json - 获得内部数据结构（BackInfoSummary）
				BackInfoSummary summary = (BackInfoSummary)JsonConvert.DeserializeObject(summaryData, typeof(BackInfoSummary));

				// 根据摘要解析异形映射配置数据 - lwf/Json/dxf 格式
				if (summary.addrEnable)
				{
					string dataType = summary.addrDataType.ToLower();

					int startAddr = Convert.ToInt32(summary.addrDataStart.Substring(2), 16);
					int dataLength = summary.addrDataLength;
					fs.Seek(startAddr, SeekOrigin.Begin);
					byte[] addrDataBytes = reader.ReadBytes(dataLength);

					// 文本格式
					if (dataType.Equals("json"))
					{
						string addrData = System.Text.Encoding.Default.GetString(addrDataBytes);
						StreamWriter writer = new StreamWriter(new FileStream(addrMapDataFilePath, FileMode.Create));
						writer.Write(addrData);
						writer.Flush();
						writer.Close();
					}
					// 二进制格式
					else if (dataType.Equals("lwf") || dataType.Equals("dxf"))
					{
						BinaryWriter writer = new BinaryWriter(new FileStream(addrMapDataFilePath, FileMode.Create));
						writer.Write(addrDataBytes);
						writer.Flush();
						writer.Close();
					}
				}
			}
			catch (Exception)
			{
				return;
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
				}
			}
		}

		// 系统配置 - 系统结构文件 - 显示菜单
		private void switchConfigButton_Click(object sender, EventArgs e)
		{
			// 设置 menu 显示位置
			this.contextMenuStrip_Switch = new System.Windows.Forms.ContextMenuStrip();
			string fontName = this.Font.Name;
			contextMenuStrip_Switch.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
			AddContextMenu("新建", contextMenuStrip_Switch.Items, newSwitchConfigFile_Click);
			AddContextMenu("打开", contextMenuStrip_Switch.Items, openSwitchConfigFile_Click);
			AddContextMenu("编辑", contextMenuStrip_Switch.Items, editSwitchConfigFile_Click);
			AddContextMenu("另存为", contextMenuStrip_Switch.Items, saveOtherSwitchConfigFile_Click);
			AddContextMenu("清除", contextMenuStrip_Switch.Items, clearSwitchConfigFile_Click);
			if (LanguageOper.available == true)
			{
				contextMenuStrip_Switch.Items[0].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.0");
				contextMenuStrip_Switch.Items[1].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.1");
				contextMenuStrip_Switch.Items[2].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.2");
				contextMenuStrip_Switch.Items[3].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.3");
				contextMenuStrip_Switch.Items[4].Text = LanguageOper.ReadValue(section, "contextSwitch.ItemsText.4");
			}
			Point pt = new Point(switchConfigButton.Location.X, switchConfigButton.Location.Y + switchConfigButton.Height);
			this.contextMenuStrip_Switch.Show(this.switchGroupBox, pt);
			this.BringToFront();
		}

		// 系统配置 - 系统结构文件 - 新建
		private void newSwitchConfigFile_Click(object sender, EventArgs e)
		{
			Form_EditSwitchConfig editForm = new Form_EditSwitchConfig(this, this.baseCoreNet, "", "new");
			this.addForm("Form_EditSwitchConfig", editForm);
			editForm.setLanguageText();
			DialogResult dr = editForm.ShowDialog();
			this.removeForm("Form_EditSwitchConfig");
			if (dr == DialogResult.OK)
			{
				string msg = "体系结构文件已更新";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.13");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

		// 系统配置 - 系统结构文件 - 打开
		private void openSwitchConfigFile_Click(object sender, EventArgs e)
		{
			// Json 格式
			OpenFileDialog o = new OpenFileDialog();
			o.Filter = "Json Files(*.json)|*.json";
			o.Multiselect = false;
			if (Directory.Exists(lastPath_SwitchConfigFile))
			{
				o.InitialDirectory = lastPath_SwitchConfigFile;
			}
			else
			{
				o.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
			}
			DialogResult dr = o.ShowDialog();
			if (dr == DialogResult.OK)
			{
				SwitchMapJson switchMapJson = preReadSwitchConfigFileJson(o.FileName);
				if (switchMapJson != null)
				{
					if (switchMapJson.map.Count > 0)
					{
						lastPath_SwitchConfigFile = (new FileInfo(o.FileName)).DirectoryName;

						switchConfigFileTextBox.Text = o.FileName;
						switchConfigFileTextBox.SelectionStart = switchConfigFileTextBox.Text.Length;
						switchConfigFileTextBox.ScrollToCaret();
						if (baseCoreNet != null)
						{
							string res = baseCoreNet.readSwitchConfigFileJson(o.FileName);
							// 更新配置文件
							if (res.Equals("success"))
							{
								setConfigValue(agentIni, "useSwitch", "true");
								setConfigValue(agentIni, "switchConfigFilePath", o.FileName);
								switchConfigFilePath = o.FileName;
								string msg = "体系结构文件已更新";
								if (LanguageOper.available == true)
								{
									msg = LanguageOper.ReadValue(section, "msgStr.13");
								}
								MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
							}
							else
							{
								setConfigValue(agentIni, "useSwitch", "false");
								setConfigValue(agentIni, "switchConfigFilePath", "");
								switchConfigFilePath = "";
								string msg = "系统结构文件读取错误";
								if (LanguageOper.available == true)
								{
									msg = LanguageOper.ReadValue(section, "msgStr.14");
								}
								MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
							}
						}
					}
					else
					{
						string msg = string.Format("系统结构文件 {0} 中不存在有效数据, 请检查", o.FileName);
						if (LanguageOper.available == true)
						{
							msg = string.Format(LanguageOper.ReadValue(section, "msgStr.15"), o.FileName);
						}
						MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
						return;
					}
				}
				else
				{
					string msg = string.Format("系统结构文件 {0} 中不存在有效数据, 请检查", o.FileName);
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.15"), o.FileName);
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return;
				}
			}
		}

		// 系统配置 - 系统结构文件 - 编辑
		private void editSwitchConfigFile_Click(object sender, EventArgs e)
		{
			Form_EditSwitchConfig editForm = new Form_EditSwitchConfig(this, this.baseCoreNet, switchConfigFileTextBox.Text.Trim(), "edit");
			this.addForm("Form_EditSwitchConfig", editForm);
			editForm.setLanguageText();
			DialogResult dr = editForm.ShowDialog();
			this.removeForm("Form_EditSwitchConfig");
			if (dr == DialogResult.OK)
			{
				string msg = "体系结构文件已更新";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.13");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

		// 系统配置 - 系统结构文件 - 另存为
		private void saveOtherSwitchConfigFile_Click(object sender, EventArgs e)
		{
			SaveFileDialog s = new SaveFileDialog();
			s.Filter = "Json Files(*.json)|*.json";
			s.FilterIndex = 1;
			if (s.ShowDialog() == DialogResult.OK)
			{
				if (switchConfigFileTextBox.Text.Equals(""))
				{
					return;
				}
				if (switchConfigFileTextBox.Text.Equals(s.FileName))
				{
					// 同名文件, 无需另存
					string msg = "体系结构文件保存完成";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.16");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return;
				}

				// 当前配置数据为从系统配置文件中提取数据
				if (switchConfigFileTextBox.Text.Equals(useInnerSwitchDataTip))
				{
					// 内部临时文件存在, 直接复制
					if (File.Exists(innerSwitchDataFilePath))
					{
						File.Copy(innerSwitchDataFilePath, s.FileName, true);
					}
					// 内部临时文件不存在, 从系统配置文件中提取数据
					else
					{
						if (File.Exists(sysConfigTextBox.Text.Trim()))
						{
							saveSwitchFileFromSysConfFile(sysConfigTextBox.Text.Trim(), s.FileName);
						}
						else
						{
							string msg = string.Format("无法找到系统配置文件 {0}", sysConfigTextBox.Text.Trim());
							if (LanguageOper.available == true)
							{
								msg = string.Format(LanguageOper.ReadValue(section, "msgStr.11"), sysConfigTextBox.Text.Trim());
							}
							MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
						}
					}
				}
				// 当前配置数据由用户指定
				else
				{
					File.Copy(switchConfigFileTextBox.Text.Trim(), s.FileName, true);
				}

				switchConfigFileTextBox.Text = s.FileName;
				switchConfigFileTextBox.SelectionStart = switchConfigFileTextBox.Text.Length;
				switchConfigFileTextBox.ScrollToCaret();
				setConfigValue(agentIni, "switchConfigFilePath", switchConfigFileTextBox.Text.Trim());

				string msg1 = "体系结构文件保存完成";
				if (LanguageOper.available == true)
				{
					msg1 = LanguageOper.ReadValue(section, "msgStr.16");
				}
				MessageBoxEx.Show(this, msg1, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

		// 系统配置 - 系统结构文件 - 清除
		private void clearSwitchConfigFile_Click(object sender, EventArgs e)
		{
			if (switchConfigFileTextBox.Text.Equals(""))
			{
				return;
			}

			string msg = "确定要清除当前的系统结构文件吗？";
			if (LanguageOper.available == true)
			{
				msg = LanguageOper.ReadValue(section, "msgStr.17");
			}
			DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

			if (dr == System.Windows.Forms.DialogResult.OK)
			{
				switchEnableCheckBox.Checked = false;

				switchConfigFileTextBox.Text = "";

				setConfigValue(agentIni, "useSwitch", "");
				setConfigValue(agentIni, "switchConfigFilePath", "");

				mainTreeGridView.Focus();
			}
		}

		// 系统配置 - 系统结构文件 - 保存体系结构文件（从系统配置文件中提取数据）
		private void saveSwitchFileFromSysConfFile(string sysConfigFilePath, string switchDataFilePath)
		{
			BinaryReader reader = null;
			FileStream fs = null;
			try
			{
				fs = new FileStream(sysConfigFilePath, FileMode.Open);
				reader = new BinaryReader(fs);
				byte[] headData = reader.ReadBytes(48);

				// 判断是否为系统配置备份文件
				if (headData[0x0000] != 0x53 || headData[0x0001] != 0x42 || headData[0x0002] != 0x41
					|| headData[0x0003] != 0x43 || headData[0x0004] != 0x4B)
				{
					string msg = "读取系统配置备份文件失败, 文件类型不匹配";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.8");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return;
				}

				// 摘要起始地址
				int summaryStart = headData[0x0014] << 24 | headData[0x0015] << 16 | headData[0x0016] << 8 | headData[0x0017];

				// 摘要数据长度
				int summaryLength = headData[0x0018] << 24 | headData[0x0019] << 16 | headData[0x001A] << 8 | headData[0x001B];

				// 读取摘要数据
				fs.Seek(summaryStart, SeekOrigin.Begin);
				byte[] summaryDataBytes = reader.ReadBytes(summaryLength);
				string summaryData = System.Text.Encoding.Default.GetString(summaryDataBytes);

				// 解析 Json - 获得内部数据结构（BackInfoSummary）
				BackInfoSummary summary = (BackInfoSummary)JsonConvert.DeserializeObject(summaryData, typeof(BackInfoSummary));

				// 根据摘要解析交换机配置数据 - Json 格式
				if (summary.switchEnable)
				{
					if (summary.switchDataType.ToLower().Equals("json"))
					{
						int startAddr = Convert.ToInt32(summary.switchDataStart.Substring(2), 16);
						int dataLength = summary.switchDataLength;
						fs.Seek(startAddr, SeekOrigin.Begin);
						byte[] switchDataBytes = reader.ReadBytes(dataLength);
						string switchData = System.Text.Encoding.Default.GetString(switchDataBytes);

						StreamWriter writer = new StreamWriter(new FileStream(switchDataFilePath, FileMode.Create));
						writer.Write(switchData);
						writer.Flush();
						writer.Close();
					}
				}
			}
			catch (Exception)
			{
				return;
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
				}
			}
		}

		// 系统配置 - 由子窗体更新系统结构文件
		public void updateSwitchConfigFileByChild(string switchConfigFilePath)
		{
			switchConfigFileTextBox.Text = switchConfigFilePath;
			switchConfigFileTextBox.SelectionStart = switchConfigFileTextBox.Text.Length;
			switchConfigFileTextBox.ScrollToCaret();
			setConfigValue(agentIni, "switchConfigFilePath", switchConfigFilePath);
		}

        // 预读 Lwf 文件, 检查内容合法性
        public bool preReadLwfFile(string lwfFilePath)
        {
            FileStream fs = null;
            BinaryReader reader = null;
            try
            {
                fs = new FileStream(lwfFilePath, FileMode.Open);
                reader = new BinaryReader(fs);

                // 读取文件头, 解析 bin 区的起始位置和长度
                byte[] header = reader.ReadBytes(0x004F);
                int binStart = header[0x30] << 24 | header[0x31] << 16 | header[0x32] << 8 | header[0x33];
                int binLength = header[0x36] << 24 | header[0x37] << 16 | header[0x38] << 8 | header[0x39];

                // 跳过 bin 区前的数据
                reader.ReadBytes(binStart - 0x004F);

                // 读取 bin 区数据
                byte[] binData = new byte[binLength];
                binData = reader.ReadBytes(binLength);

                int subNumInBin = binData[0x102] << 8 | binData[0x0103];
                int maxValue = 0;
                for (int i = 0; i < subNumInBin; i++)
                {
                    int tmpValue = binData[0x1000 + i * 16 + 2] << 8 | binData[0x1000 + i * 16 + 3];
                    if (tmpValue > maxValue)
                    {
                        maxValue = tmpValue;
                    }
                }
                int maxLampNumInBin = maxValue;

                return true;
            }
            catch (Exception)
            {
                return false;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }

		// 系统配置 - 开启/关闭异形映射 - 逻辑动作
		private void setAddrMapEnable(bool enable)
		{
			if (enable)
			{
				if (addrMapFileType.Equals("lwf"))
				{
					if (!addrMapFilePath.Equals(""))
					{
                        fillSubTubDataList(addrMapFilePath);
						// 更新界面显示及配置文件
						if (!addrMapFilePath.Equals(innerAddrDataFilePath))
						{
							addrMapFileTextBox.Text = addrMapFilePath;
							addrMapFileTextBox.SelectionStart = addrMapFileTextBox.Text.Length;
							addrMapFileTextBox.ScrollToCaret();

                            setConfigValue(agentIni, "addrMapEnable", "true");
							setConfigValue(agentIni, "addrMapFilePath", addrMapFilePath);
							setConfigValue(agentIni, "addrMapFileType", addrMapFileType);
						}

						// 更新底层状态
						if (baseCoreNet != null)
						{
							Thread t_core = new Thread(() => 
							{
                                baseCoreNet.readLwfAndBuildMapTable(addrMapFilePath, true);
                                baseCoreNet.setAddrMapEnable(true);
							});
							t_core.IsBackground = true;
							t_core.Start();
						}
                        Thread.Sleep(100);
                        rbFromLwf.Checked = true;
                        rbManual.Checked = false;
						return;
					}
				}

				// 操作发生异常
				string msg = "";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.19");
				}
				MessageBoxEx.Show(this, msg + "fileType = " + addrMapFileType + "\n" + "filePath = " + addrMapFilePath, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
			else
			{
				// 更新配置文件
				setConfigValue(agentIni, "addrMapEnable", "false");

				// 更新底层状态
				if (baseCoreNet != null)
				{
                    baseCoreNet.setAddrMapEnable(false);
                }

                subTubeDataList.Clear();
                rbFromLwf.Checked = false;
                rbManual.Checked = true;
			}
		}

		// 系统配置 - 开启/关闭多路交换机
		private void switchEnableCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			if (initDone == false)
			{
				return;
			}

			if (switchCheckAction == false)
			{
				return;
			}

			if (switchEnableCheckBox.Checked)
			{
				if (switchConfigFileTextBox.Text.Trim().Equals(""))
				{
					Form_NewOrSelect newOrSelectForm = new Form_NewOrSelect();
					this.addForm("Form_NewOrSelect", newOrSelectForm);
					newOrSelectForm.setLanguageText();
					DialogResult dr = newOrSelectForm.ShowDialog();
					this.removeForm("Form_NewOrSelect");
					// 新建文件
					if (dr == DialogResult.OK)
					{
						newSwitchConfigFile_Click(null, null);
					}
					//打开现有文件
					else if (dr == DialogResult.Yes)
					{
						openSwitchConfigFile_Click(null, null);
					}
				}

				if (!switchConfigFileTextBox.Text.Trim().Equals(""))
				{
					string switchConfigFilePath = switchConfigFileTextBox.Text.Trim();
					bool saveIni = true;
					if (switchConfigFileTextBox.Text.Trim().Equals(useInnerSwitchDataTip))
					{
						switchConfigFilePath = innerSwitchDataFilePath;
						saveIni = false;
					}

					if (File.Exists(switchConfigFilePath))
					{
						// 参数完整 - 启用多路交换机
						if (baseCoreNet != null)
						{
							baseCoreNet.readSwitchConfigFileJson(switchConfigFilePath);
							baseCoreNet.setUseSwitch(true);
						}

						if (saveIni)
						{
							setConfigValue(agentIni, "useSwitch", "true");
							setConfigValue(agentIni, "switchConfigFilePath", switchConfigFilePath);
						}

						switchConfigButton.Enabled = true;
						switchConfigFileTextBox.Enabled = true;
					}
					else
					{
						if (switchConfigFileTextBox.Text.Trim().Equals(useInnerSwitchDataTip))
						{
							// 从系统配置文件中恢复系统结构数据
							if (File.Exists(sysConfigTextBox.Text.Trim()))
							{
								saveSwitchFileFromSysConfFile(sysConfigTextBox.Text.Trim(), innerSwitchDataFilePath);

								// 参数完整 - 启用多路交换机
								if (baseCoreNet != null)
								{
									baseCoreNet.readSwitchConfigFileJson(switchConfigFilePath);
									baseCoreNet.setUseSwitch(true);
								}

								if (saveIni)
								{
									setConfigValue(agentIni, "useSwitch", "true");
									setConfigValue(agentIni, "switchConfigFilePath", innerSwitchDataFilePath);
								}

								switchConfigButton.Enabled = true;
								switchConfigFileTextBox.Enabled = true;
							}
							else
							{
								string msg = string.Format("无法找到系统配置文件 {0}", sysConfigTextBox.Text.Trim());
								if (LanguageOper.available == true)
								{
									msg = string.Format(LanguageOper.ReadValue(section, "msgStr.11"), sysConfigTextBox.Text.Trim());
								}
								MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
								return;
							}
						}
						else
						{
							string msg = string.Format("文件 {0} 不存在", switchConfigFileTextBox.Text.Trim());
							if (LanguageOper.available == true)
							{
								msg = string.Format(LanguageOper.ReadValue(section, "msgStr.18"), switchConfigFileTextBox.Text.Trim());
							}
							MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
						}

						// 参数不完整 - 关闭多路交换机
						if (baseCoreNet != null)
						{
							baseCoreNet.setUseSwitch(false);
						}
						switchEnableCheckBox.Checked = false;
						switchConfigFileTextBox.Text = "";
						setConfigValue(agentIni, "useSwitch", "false");
						setConfigValue(agentIni, "switchConfigFilePath", "");
					}
				}
				else
				{
					switchEnableCheckBox.Checked = false;
					switchConfigButton.Enabled = false;
					switchConfigFileTextBox.Enabled = false;
				}
			}
			else
			{
				if (baseCoreNet != null)
				{
					baseCoreNet.setUseSwitch(false);
				}
				setConfigValue(agentIni, "useSwitch", "false");
				switchConfigButton.Enabled = false;
				switchConfigFileTextBox.Enabled = false;
			}

			mainTreeGridView.Nodes.Clear();
		}

		// 系统配置 - 预读多路交换机配置文件
		public string preReadSwitchConfigFile(string configFilePath)
		{
			StreamReader reader = null;
			try
			{
				// 读取配置文件
				reader = new StreamReader(configFilePath);
				string currentLine = null;
				Regex r = new Regex(@"^([0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F])$");
				while (true)
				{
					currentLine = reader.ReadLine();

					if (currentLine == null)
					{
						break;
					}
					else if (currentLine.Trim().Equals(""))
					{
						continue;
					}
					else if (currentLine.Trim().StartsWith("#"))
					{
						continue;
					}

					string[] subStrs = currentLine.Split(',');

					// 检查 MAC 地址的合法性
					if (r.IsMatch(subStrs[1].Trim().Replace("-", "").Replace(":", "")))
					{
						continue;
					}
					else
					{
						string s = string.Format("MAC地址格式不正确（{0}）, 请检查", subStrs[1].Trim());
						if (LanguageOper.available == true)
						{
							s = string.Format(LanguageOper.ReadValue(section, "msgStr.40"), subStrs[1].Trim());
						}
						return s;
					}
				}
				return "success";
			}
			catch (Exception)
			{
				return "error";
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
				}
			}
		}

		// 系统配置 - 预读多路交换机配置文件 - Json 格式
		public SwitchMapJson preReadSwitchConfigFileJson(string configFilePath)
		{
			StreamReader reader = null;
			try
			{
				StringBuilder jsonDataBuilder = new StringBuilder();
				// 读取配置文件
				reader = new StreamReader(new FileStream(configFilePath, FileMode.Open));
				string currentLine = null;
				while (true)
				{
					currentLine = reader.ReadLine();
					if (currentLine == null)
					{
						break;
					}
					else
					{
						jsonDataBuilder.Append(currentLine);
					}
				}

				// 解析 Json
				SwitchMapJson switchMapJson = (SwitchMapJson)JsonConvert.DeserializeObject(jsonDataBuilder.ToString(), typeof(SwitchMapJson));

				// 检查 Mac 地址的正则表达式
				Regex r = new Regex(@"^([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])$");

				// 检查解析后的数据
				foreach (SwitchMapJsonUnit unit in switchMapJson.map)
				{
					// 检查 SubIndex
					int subIndex = -1;
					if (int.TryParse(unit.SubIndex, out subIndex) == false)
					{
						return null;
					}
					else if (subIndex < 1)
					{
						return null;
					}

					// 检查 Mac 地址
					if (r.IsMatch(unit.Mac.Trim().Replace("-", "").Replace(":", "")))
					{
						continue;
					}
					else
					{
						return null;
					}
				}

				return switchMapJson;

			}
			catch (Exception)
			{
				return null;
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
				}
			}
		}

		// 系统配置 - 下载/清除布线总入口
		private void downloadLwfButton_Click(object sender, EventArgs e)
		{
			Form_DownloadLwf formDownloadLwf = new Form_DownloadLwf(baseCoreNet, this, addrMapFilePath);
			this.addForm("Form_DownloadLwf", formDownloadLwf);
			formDownloadLwf.setLanguageText();
			formDownloadLwf.ShowDialog();
			this.removeForm("Form_DownloadLwf");
		}

        public void readLampParaButtonClick() {
            readLampParaButton_Click(null, null);
        }

		// 系统配置 - 从布线文件中获取灯具参数
        private void readLampParaButton_Click(object sender, EventArgs e)
        {
            if (addrMapFileTextBox.Text.Equals(""))
            {
                return;
            }

            if (!File.Exists(addrMapFilePath))
            {
                string msg = string.Format("文件 {0} 不存在", addrMapFilePath);
                if (LanguageOper.available == true)
                {
                    msg = string.Format(LanguageOper.ReadValue(section, "msgStr.18"), addrMapFilePath);
                }
                MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
                return;
            }

            Thread t = new Thread(() =>
            {
                while (lampParaIsReadingFromFile)
                {
                    Thread.Sleep(5);
                }

                lampParaIsReadingFromFile = true;
                this.BeginInvoke(setLampParaIsReadingDelegate, true);

                LampPara lampPara = readLampPara(addrMapFileType, addrMapFilePath);
                if (lampPara != null)
                {
                    Invoke(new MethodInvoker(() =>
                    {
                        if (frmLwfPara != null) {
                            frmLwfPara.UpdateLwfPara(lampPara.xPointNum, lampPara.yPointNum, lampPara.subControlNum, lampPara.totalLampNum);
                        }
                        
                    }));
                }
                else
                {
                    string msg = string.Format("布线文件 {0} 中的灯具参数读取错误", addrMapFileTextBox.Text);
                    if (LanguageOper.available == true)
                    {
                        msg = string.Format(LanguageOper.ReadValue(section, "msgStr.20"), addrMapFileTextBox.Text);
                    }
                    Invoke(new MethodInvoker(() =>
                    {
                        MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
                    }));
                }

                this.BeginInvoke(setLampParaIsReadingDelegate, false);
                lampParaIsReadingFromFile = false;

            });
            t.IsBackground = true;
            t.Start();
        }

		// 系统配置 - 从布线文件中获取灯具参数 - 逻辑动作
		private LampPara readLampPara(string fileType, string filePath)
		{
			Console.WriteLine("readLampPara, fileType = " + fileType + ", filePath = " + filePath);

			// lwf 格式
			if (fileType.Equals("lwf"))
			{
				return readLampParaLwf(fileType, filePath);
			}
			else
			{
				return null;
			}
		}

        // 获得应用程序 exe 所在路径
        private string getAppPath()
        {
            string path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;

            path = path.Substring(0, path.LastIndexOf("\\"));

            return path;
        }

		// 系统配置 - 从布线文件中获取灯具参数 - lwf 格式
		private LampPara readLampParaLwf(string fileType, string filePath)
		{
			LampPara lampPara = new LampPara();
            //FileStream fs = null;
            //BinaryReader reader = null;
            try
            {
            //    fs = new FileStream(filePath, FileMode.Open);
            //    reader = new BinaryReader(fs);

            //    // 读取文件头, 解析 bin 区的起始位置和长度
            //    byte[] header = reader.ReadBytes(0x004F);
            //    int binStart = header[0x30] << 24 | header[0x31] << 16 | header[0x32] << 8 | header[0x33];
            //    int binLength = header[0x36] << 24 | header[0x37] << 16 | header[0x38] << 8 | header[0x39];

            //    // 跳过 bin 区前的数据
            //    reader.ReadBytes(binStart - 0x004F);

            //    // 读取 bin 区数据
            //    byte[] binData = reader.ReadBytes(binLength);

            //    // 控制器个数
            //    int subNumInBin = binData[0x102] << 8 | binData[0x0103];
            //    lampPara.subControlNum = subNumInBin;

            //    // 有效灯个数
            //    int effectLampNum = binData[0x104] << 24 | binData[0x105] << 16 | binData[0x106] << 8 | binData[0x0107];
            //    lampPara.totalLampNum = effectLampNum;

            //    // 控制器端口最大灯点数
            //    int maxValue = 0;
            //    for (int i = 0; i < subNumInBin; i++)
            //    {
            //        int tmpValue = binData[0x1000 + i * 16 + 2] << 8 | binData[0x1000 + i * 16 + 3];
            //        if (tmpValue > maxValue)
            //        {
            //            maxValue = tmpValue;
            //        }
            //    }
            //    int maxLampNumInBin = maxValue;

            //    // 水平点数、垂直点数
            //    int xPointNum = 0;
            //    int yPointNum = 0;
            //    int[] portLampNum = null;
            //    for (int i = 0; i < subNumInBin; i++)
            //    {
            //        SubControl subControl = new SubControl();

            //        // 控制器最大端口个数
            //        int portNum = binData[0x1000 + i * 16 + 0] << 8 | binData[0x1000 + i * 16 + 1];
            //        subControl.DeclareSubPortNum = portNum;
            //        portLampNum = new int[portNum];

            //        // 控制器单个端口最多灯点数
            //        int maxLampNumPerPort = binData[0x1000 + i * 16 + 2] << 8 | binData[0x1000 + i * 16 + 3];
            //        for (int j = 0; j < maxLampNumPerPort; j++)
            //        {
            //            for (int k = 0; k < portNum; k++)
            //            {
            //                int y = binData[0x8000 + i * 32768 + j * portNum * 4 + k * 4 + 0] << 8 | binData[0x8000 + i * 32768 + j * portNum * 4 + k * 4 + 1];
            //                int x = binData[0x8000 + i * 32768 + j * portNum * 4 + k * 4 + 2] << 8 | binData[0x8000 + i * 32768 + j * portNum * 4 + k * 4 + 3];
            //                if (xPointNum < x)
            //                {
            //                    xPointNum = x;
            //                }
            //                if (yPointNum < y)
            //                {
            //                    yPointNum = y;
            //                }
            //            }
            //        }
            //    }

            //    //MessageBoxEx.Show(this, "tmpTotalNum = " + tmpTotalNum + ", xPointNum = " + xPointNum + ", yPointNum = " + yPointNum);

            //    // 坐标从(0,0)点开始, 需要 + 1
            //    lampPara.xPointNum = xPointNum + 1;
            //    lampPara.yPointNum = yPointNum + 1;

            //    // 最大通道数 = 所有控制器所有端口的最大灯点个数
            //    lampPara.maxChannelNum = maxLampNumInBin;
                string xmlFileName = getAppPath() + @"\lwf-info.xml";

                // 判断文件是否存在
                if (File.Exists(filePath) == false)
                {
                    return null;
                }

                FileStream fsLwf = new FileStream(filePath, FileMode.Open);
                FileStream fsXml = new FileStream(xmlFileName, FileMode.Create);
                if (fsLwf.Length == 0)
                {
                    return null;
                }

                byte[] lwfFileBytes = new byte[fsLwf.Length];

                BinaryWriter bw = new BinaryWriter(fsXml);
                fsLwf.Read(lwfFileBytes, 0, (int)fsLwf.Length);

                int length = lwfFileBytes[0x26] << 24 | lwfFileBytes[0x27] << 16 | lwfFileBytes[0x28] << 8 | lwfFileBytes[0x29];

                byte[] xmlFileBytes = new byte[length];
                for (int i = 0; i < length; i++)
                {
                    xmlFileBytes[i] = lwfFileBytes[0x100 + i];
                }
                bw.Write(xmlFileBytes);

                bw.Close();
                fsXml.Close();
                fsLwf.Close();

                /**************************************************************************/

                XmlDocument xmlDoc = new XmlDocument();
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.IgnoreComments = true;
                XmlReader xmlReader = XmlReader.Create(xmlFileName, settings);
                xmlDoc.Load(xmlReader);
                xmlReader.Close();

                SystemTubeDataStore systemTubeDataStore = XmlReadWrite.ParseLwfXmlData(xmlDoc);

                lampPara.subControlNum = systemTubeDataStore.subTube.s_num;
                lampPara.xPointNum = systemTubeDataStore.systemTube.x;
                lampPara.yPointNum = systemTubeDataStore.systemTube.y;
                int lampCount = 0;
                int maxLamp = 0;
                foreach(SubData dat in systemTubeDataStore.subTube.subDataList)
                {
                    for (int i = 0; i < dat.p_num; i++)
                    {
                        lampCount += dat.portLampNumList[i];
                        if (dat.portLampNumList[i] > maxLamp)
                        {
                            maxLamp = dat.portLampNumList[i];
                        }
                    }
                }
                lampPara.totalLampNum = lampCount;
                lampPara.maxChannelNum = maxLamp * 3;

                if (File.Exists(xmlFileName))
                {
                    try
                    {
                        File.Delete(xmlFileName);
                    }
                    catch (Exception)
                    {
                    }
                }


				return lampPara;
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + ex.StackTrace);
				return null;
			}
		}

		// 系统配置 - 设置读取灯具参数按钮状态
		private void setLampParaIsReading(bool isReading)
		{
            //if (isReading)
            //{
            //    btnLwfFileInfo.Text = "读取中";
            //    if (LanguageOper.available == true)
            //    {
            //        btnLwfFileInfo.Text = LanguageOper.ReadValue(section, "readLampParaButton.Text.0");
            //    }
            //    btnLwfFileInfo.Enabled = false;
            //}
            //else
            //{
            //    btnLwfFileInfo.Text = "读取灯具参数";
            //    if (LanguageOper.available == true)
            //    {
            //        btnLwfFileInfo.Text = LanguageOper.ReadValue(section, "readLampParaButton.Text.1");
            //    }
            //    btnLwfFileInfo.Enabled = true;
            //}
		}

		// 系统配置 - 固化分控序号
		private void fixSubPositionButton_Click(object sender, EventArgs e)
		{
			Form_FixSubPos fixSubPosForm = new Form_FixSubPos(baseCoreNet);
			this.addForm("Form_FixSubPos", fixSubPosForm);
			fixSubPosForm.setLanguageText();
			fixSubPosForm.ShowDialog();
			this.removeForm("Form_FixSubPos");
		}

        public void fixSubPositionButtonPerformClick() {
            fixSubPositionButton_Click(null, null);
        }

        // 系统配置 - 设置ArtNet信息
        private void SetArtUnvButton_Click(object sender, EventArgs e)
        {
            Form_ArtNetSet artNetSetForm = new Form_ArtNetSet(baseCoreNet);
            this.addForm("Form_ArtNetSet", artNetSetForm);
            artNetSetForm.setLanguageText();
            artNetSetForm.ShowDialog();
            this.removeForm("Form_ArtNetSet");
        }

		// 系统配置 - 清除分控序号
		private void clearSubPositionButton_Click(object sender, EventArgs e) {

        }

        public void clearSubPositionButtonPerformClick() {
            clearSubPositionButton_Click(null, null);
        }

		#endregion

		#region Tab 分控设置 - 业务逻辑

		// 查询当前的分控配置数据
		public byte[] getSubConfigData()
		{
			return rvCardL9Config.GetSubData();
		}

		// 查询当前的分控配置文件路径
		public string getSubConfigFilePath()
		{
			if (subFileNameTextBox.Text.Equals(""))
			{
				return "default.sub";
			}
			else
			{
				return subFileNameTextBox.Text;
			}
		}

		// 分控设置 - 检查端口带载参数变化
		private void cmbChannelNum_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (cmbChannelNumActionEnable)
			{
                checkFactLampNum();
			}
		}

        // 分控设置 - 检查端口带载参数变化
        private void cmbChannelNum_TextChanged(object sender, EventArgs e) {
            if (cmbChannelNumActionEnable) {
                checkFactLampNum();
            }
        }

		// 分控设置 - 检查端口带载参数合法性
		private bool checkFactLampNum()
		{
            var tmpFactLampNum = 0;
            var valid = true;
            if (!int.TryParse(cmbChannelNum.Text, out tmpFactLampNum)) {
                valid = false;
            } else {
                tmpFactLampNum = (int)Math.Ceiling((decimal)tmpFactLampNum / 3);
                if (tmpFactLampNum < 0) {
                    valid = false;
                }
            }

            if (!valid) {
                string msg = "端口带载数输入有误，应为 [0,896] 区间的整数";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "msgStr.25");
                }
                MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
                return false;
            }

            rvCardL9Config.pixelLength = tmpFactLampNum;
			if (rvCardL9Config.pixelLength > rvCardL9Config.maxPixelLength)
			{
				string msg = "端口带载数超过最大带载数限制";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.26");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
                cmbChannelNum.Text = (rvCardL9Config.maxPixelLength * 3).ToString();
				return false;
			}
			else
			{
                //cmbChannelNum.Text = (rvCardL9Config.pixelLength * 3).ToString();
			}

			return true;
		}

		// 分控设置 - 从 sub 文件中读取配置
		private void loadFromSub(string filePath)
		{
			rvCardL9Config.LoadFromSub(filePath);
			m_LoadClockFromSub = true;
			m_LoadGrayFromSub = true;
		}

		// 分控设置 - 获得 sub 文件路径
		private string getSubFileName()
		{
			// 默认为 /conf/defaultL9.sub
			string defaultSubFilePath = ZqConfig.GetAppPath() + @"\conf\defaultL9.sub";

			// 从 /conf/Config2012.ini 中读取配置
			string lastOpenSub = ZqConfig.ReadValueString("SUBPath", "SUBL9", config2012Ini);

			if (File.Exists(lastOpenSub))
			{
				return lastOpenSub;	// 上次保存的 sub 文件
			}
			else
			{
				string msg = string.Format("分控配置：未能找到文件 {0}, 将使用默认文件 defaultL9.sub", lastOpenSub);
				if (LanguageOper.available == true)
				{
					msg = string.Format(LanguageOper.ReadValue(section, "msgStr.27"), lastOpenSub);
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				
				if (File.Exists(defaultSubFilePath))
				{
					return defaultSubFilePath;	// 默认的 sub 文件 - /conf/defaultL9.sub
				}
				else
				{
					return "internal";			// 内部预置的 defaultL9.sub
				}
			}
		}

		// 分控设置 - 初始化分控设置界面信息
		private void initChipSetTab()
		{
			// dxf 默认处理
			int[] dxfData = new int[4];
			m_DxfFilePath = rvCardL9Config.dxfFileName;
			rvCardL9Config.GetDxfData(dxfData);
			m_HResolution = dxfData[0];
			m_VResolution = dxfData[1];
			m_DxfSubControlNum = dxfData[2];
			m_DxfLampNum = dxfData[3];

			// 更新主界面
			reloadL9Interface();
		}

		// 分控设置 - 初始化芯片菜单
		private void initChipMenu()
		{
			// 读取 chip 信息
			string appPath = ZqConfig.GetAppPath();
			string chipInfoFilePath = appPath + @"\conf\L9Chip.ini";

			// 判断文件是否存在
			if (ZqConfig.IsFileExist(chipInfoFilePath) == false)
			{
				string msg = string.Format("文件 {0} 不存在", chipInfoFilePath);
				if (LanguageOper.available == true)
				{
					msg = string.Format(LanguageOper.ReadValue(section, "msgStr.18"), chipInfoFilePath);
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Warning);
				
				return;
			}

			// 初始化芯片文件路径
			m_ChipInfoFileName = chipInfoFilePath;

			// 读取所有芯片类型
			string chipNameArrayStr = ZqConfig.ReadValueString("ChipType", "Total", m_ChipInfoFileName);

			// 分割得出所有芯片类型
			m_MainMenuItemArray = chipNameArrayStr.Split(new char[] { '-' });

			// 添加芯片菜单项
			this.contextMenuStrip_Chip = new System.Windows.Forms.ContextMenuStrip();
			ToolStripMenuItem subItem = new ToolStripMenuItem();
			for (int i = 0; i < m_MainMenuItemArray.Length; i++)
			{
				// 添加 1 级菜单项
				subItem = AddContextMenu(m_MainMenuItemArray[i], contextMenuStrip_Chip.Items, null);

				// 读取单个芯片定义
				string sigleChipType = ZqConfig.ReadValueString("ChipType", m_MainMenuItemArray[i], m_ChipInfoFileName);

				// 分割得到单个芯片类型定义
				m_ChildMenuItemArray = sigleChipType.Split(new char[] { '-' });

				// 添加 2 级菜单项
				for (int j = 0; j < m_ChildMenuItemArray.Length; j++)
				{
					AddContextMenu(m_ChildMenuItemArray[j], subItem.DropDownItems, subItem_Click);
				}
			}
		}

		// 分控设置 - 菜单创建基本函数
		private ToolStripMenuItem AddContextMenu(string text, ToolStripItemCollection cms, EventHandler callback)
		{
			if (text == "-")
			{
				ToolStripSeparator tsp = new ToolStripSeparator();
				cms.Add(tsp);
				return null;
			}
			else if (!string.IsNullOrEmpty(text))
			{
				ToolStripMenuItem tsmi = new ToolStripMenuItem(text);
				if (callback != null)
				{
					tsmi.Click += callback;
				}
				cms.Add(tsmi);
				return tsmi;
			}

			return null;
		}

		// 分控设置 - 切换芯片类型
		private void subItem_Click(object sender, EventArgs e)
		{
			ToolStripMenuItem tsmi = (ToolStripMenuItem)sender;

			chipName = tsmi.Text;
			m_LoadGrayFromSub = true;

			// 加载芯片所有设置（从L9Chip.ini读取）
			getDefaultChipInfoFromFile();

			m_LoadClockFromSub = true;
			m_LoadGrayFromSub = true;

			// 更新主界面
			rvCardL9Config.colorOrderMode = 0;
			reloadL9Interface();

			chipJustChanged = true;
		}

		// 分控设置 - 加载芯片所有设置（从L9Chip.ini读取）
		private void getDefaultChipInfoFromFile()
		{
			int chipNo = ZqConfig.ReadValueInt(chipName, "No", m_ChipInfoFileName);
			rvCardL9Config.chipType = chipNo;

			int tube_ic_num = 0;		// 缺省每单元芯片数芯片个数
			int rube_pixel_hight = 0;	// 缺省每单元像素宽度
			int rube_pixel_width = 0;	// 缺省每单元像素高度
			bool chipColorModeInited = false;
			bool subNoInited = false;
			bool fourChannelInited = false;
			bool currentAdjEnInited = false;

			List<string> chipKey = new List<string>(200);
			List<string> chipValue = new List<string>(200);

			ZqConfig.GetSection(chipName, m_ChipInfoFileName, chipKey, chipValue);

			if (chipKey.Count == 0 || chipValue.Count == 0)
			{
				return;
			}

			for (int i = 0; i < chipKey.Count; i++)
			{
				chipKey[i] = chipKey[i].Trim();
				chipValue[i] = chipValue[i].Trim();

				// 该芯片在FPGA程序中对应的编号
				if (chipKey[i] == "No")
				{
					rvCardL9Config.chipType = Convert.ToInt32(chipValue[i]);
				}
				// 该芯片在FPGA编号下方的子编号，与FPGA编号共同决定芯片编号
				if (chipKey[i] == "subNo")
				{
					rvCardL9Config.subNo = Convert.ToInt32(chipValue[i]);
					subNoInited = true;
				}
				// 每颗芯片通道数
				if (chipKey[i] == "channel")
				{
					if (chipValue[i].ToLower().Equals("manual"))
					{
						rvCardL9Config.channel = 3;
						rvCardL9Config.channelManualEnable = true;
					}
					else
					{
						rvCardL9Config.channel = Convert.ToInt32(chipValue[i]);
						rvCardL9Config.channelManualEnable = false;
					}
				}
				// 四色模式下的通道数
				if (chipKey[i] == "channel_4color")
				{
					rvCardL9Config.channel4Color = Convert.ToInt32(chipValue[i]);
					fourChannelInited = true;
				}
				// 每颗芯片数据包长度（bit）
				if (chipKey[i] == "packet_len")
				{
					rvCardL9Config.packetLen = Convert.ToInt32(chipValue[i]);
				}
				// 是否是双倍数据传输速度（这个参数将会影响到性能参数计算）
				if (chipKey[i] == "ddr")
				{
					string str = ZqConfig.ReadValue(chipName, "ddr", m_ChipInfoFileName);
					str = str.Substring(0, 2);
					if (str.ToLower().Equals("no"))
						rvCardL9Config.doubleSpeed = 0;
					else
						rvCardL9Config.doubleSpeed = 1;
				}
				// 列映射表是否逆序
				if (chipKey[i] == "reverse")
				{
					string str = ZqConfig.ReadValue(chipName, "reverse", m_ChipInfoFileName);
					if (str.ToLower().Equals("no"))
						rvCardL9Config.columnMapReverse = 0;
					else
						rvCardL9Config.columnMapReverse = 1;
				}
				if (chipKey[i] == "data_level")
				{
					rvCardL9Config.dataEffect = Convert.ToInt32(chipValue[i]);
				}
				if (chipKey[i] == "oe_level")
				{
					rvCardL9Config.oeEffect = Convert.ToInt32(chipValue[i]);
				}
				// 每端口最大带载点数
				if (chipKey[i] == "max_payload")
				{
					rvCardL9Config.maxPixelLength = Convert.ToInt32(chipValue[i]);
				}
				// 缺省每端口实际带载点数
				if (chipKey[i] == "actual_playload")
				{
					rvCardL9Config.pixelLength = Convert.ToInt32(chipValue[i]);
                    rvCardL9Config.pixelLength = rvCardL9Config.maxPixelLength; // 目前默认为最大带载点数
				}
				// 缺省时钟频率列表值
				if (chipKey[i] == "clockListIndex")
				{
					rvCardL9Config.clockFreqIndex = Convert.ToInt32(chipValue[i]);
				}
				// 占空比
				if (chipKey[i] == "clockduty")
				{
					rvCardL9Config.clockDuty = Convert.ToDouble(chipValue[i]) / 100.0;
				}
				// 灰度等级
				if (chipKey[i] == "graylevel")
				{
					// 最小灰度等级等于最大灰度等级
					if (chipValue[i + 1] == chipValue[i + 2])
					{
						int grayLevel = Convert.ToInt32(chipValue[i]);
						string max_gray_str = ZqConfig.ReadValue(chipName, "grayLevelMax", m_ChipInfoFileName);
						string min_gray_str = ZqConfig.ReadValue(chipName, "grayLevelMin", m_ChipInfoFileName);
						int max_gray = Convert.ToInt32(max_gray_str);
						int min_gray = Convert.ToInt32(min_gray_str);
						int m = max_gray - grayLevel;
						rvCardL9Config.grayLevelList.Clear();
						int num = Convert.ToInt32(Math.Pow(2, Convert.ToDouble(max_gray)));
						for (int s = max_gray; s >= min_gray; s--)
						{
							int grayValue = Convert.ToInt32(Math.Pow(2, (double)s));
							rvCardL9Config.grayLevelList.Add(grayValue);
						}
						rvCardL9Config.SetGrayIndex(m);
					}
				}
				// 缺省Gamma值
				if (chipKey[i] == "default_gamma")
				{
					rvCardL9Config.SetGamma(Convert.ToDouble(chipValue[i]));
					gammaLabel.Text = rvCardL9Config.gamma.ToString();
				}
				// 缺省起灰值
				if (chipKey[i] == "default_graystart")
				{
					rvCardL9Config.SetGrayStart(Convert.ToInt32(chipValue[i]));
					grayStartLabel.Text = rvCardL9Config.startGray.ToString();
				}
				// 缺省低灰平滑度
				if (chipKey[i] == "default_low_gray_smooth")
				{
					int lowGraySmooth = Convert.ToInt32(chipValue[i]);
					if (lowGraySmooth > 10)
					{
						lowGraySmooth = 10;
					}
					rvCardL9Config.SetLowGraySmooth(lowGraySmooth);
				}
				// 芯片空脚显示的灰度值
				if (chipKey[i] == "blank_gray")
				{
					rvCardL9Config.blankGrayBin = Convert.ToInt32(chipValue[i]);
				}
				// 缺省每单元芯片数
				if (chipKey[i] == "tube_ic_num")
				{
					tube_ic_num = Convert.ToInt32(chipValue[i]);
					if (tube_ic_num > 64)
					{
						tube_ic_num = 64;
					}
					rvCardL9Config.unitChipNum = tube_ic_num;
				}
				// 缺省每单元像素高度
				if (chipKey[i] == "rube_pixel_hight")
				{
					rube_pixel_hight = Convert.ToInt32(chipValue[i]);
					if (rube_pixel_hight > 64)
					{
						rube_pixel_hight = 64;
					}
					rvCardL9Config.unitPixelHight = rube_pixel_hight;
				}
				// 缺省每单元像素宽度
				if (chipKey[i] == "rube_pixel_width")
				{
					rube_pixel_width = Convert.ToInt32(chipValue[i]);
					if (rube_pixel_width > 64)
					{
						rube_pixel_width = 64;
					}
					rvCardL9Config.unitPixelWidth = rube_pixel_width;
				}
				// 颜色模式
				if (chipKey[i] == "colorListLength")
				{
					chipColorModeInited = true;
					int colorListLength = Convert.ToInt32(chipValue[i]);
					string strchipselect = ZqConfig.ReadValue(chipName, "colorListIndex", m_ChipInfoFileName);
					string str = Convert.ToInt32(strchipselect).ToString();
					string strcolor = "color" + str;
					strcolor = ZqConfig.ReadValue(chipName, strcolor, m_ChipInfoFileName);
					int colormode = Convert.ToInt32(strcolor);
					rvCardL9Config.SetSelectedChipMode(colormode);
					rvCardL9Config.fourColorMode = 0;
					rvCardL9Config.useChipNum = 1;
					colorModeList.Clear();
					// 更新颜色模式列表
					for (int k = 0; k < colorListLength; k++)
					{
						string str_num = "color" + k.ToString();
						string temp = ZqConfig.ReadValue(chipName, str_num, m_ChipInfoFileName);
						if (temp == "")
						{
							string msg = string.Format("芯片 {0} 的 {1} 不存在，请确认芯片配置文件正确", chipName, str_num);
							if (LanguageOper.available == true)
							{
								msg = string.Format(LanguageOper.ReadValue(section, "msgStr.28"), chipName, str_num);
							}
							MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
							continue;
						}
						colorModeList.Add(Convert.ToInt32(temp));
					}
				}
				// 电流调节使能
				if (chipKey[i] == "current_adj_en")
				{
					rvCardL9Config.currentAdjustEnable = Convert.ToInt32(chipValue[i]);
					currentAdjEnInited = true;
				}
				// 是否特殊处理
				if (chipKey[i] == "current_addr_special")
				{
					rvCardL9Config.currentAdjustSpecial = Convert.ToInt32(chipValue[i]);
				}
				// 电流调节通道数
				if (chipKey[i] == "current_channel_max")
				{
					rvCardL9Config.currentChannelMax = Convert.ToInt32(chipValue[i]);
				}
				// 电流调节级数
				if (chipKey[i] == "current_level_max")
				{
					rvCardL9Config.currentLevelMax = Convert.ToInt32(chipValue[i]);
				}
				// 电流调节默认级数
				if (chipKey[i] == "current_level_default")
				{
					rvCardL9Config.currentLevelDefault = Convert.ToInt32(chipValue[i]);
					rvCardL9Config.currentIndexList.Clear();
					for (int index_num = 0; index_num < rvCardL9Config.currentChannelMax; index_num++)
					{
						rvCardL9Config.currentIndexList.Add(rvCardL9Config.currentLevelDefault);
					}
				}
			}
            rvCardL9Config.pixelLength = rvCardL9Config.maxPixelLength;
			// 没有找到电流使能设置
			if (currentAdjEnInited == false)
			{
				rvCardL9Config.currentAdjustEnable = 0;
			}
			// 没有找到颜色模式
			if (chipColorModeInited == false)
			{
				rvCardL9Config.SetSelectedChipMode(3);
				rvCardL9Config.useChipNum = 1;
				colorModeList.Clear();
				colorModeList.Add(3);
			}
			// 没有找到 subNo 属性
			if (subNoInited == false)
			{
				rvCardL9Config.subNo = 0;
			}
			// 没有找到 4 色模式下的通道数
			if (fourChannelInited == false)
			{
				rvCardL9Config.channel4Color = 4;
			}

			// 重置通道亮度
			rvCardL9Config.brightR = 255;
			rvCardL9Config.brightG = 255;
			rvCardL9Config.brightB = 255;
			rvCardL9Config.brightW = 255;
		}

		// 保存当前配置至 defaultL9.sub
		private void saveCurrentChipConfig()
		{
			string defaultL9Path = ZqConfig.GetAppPath() + @"\conf\defaultL9.sub";
			try
			{
				rvCardL9Config.SaveToSub(defaultL9Path, 0x080200);
			}
			catch (Exception ex)
			{
				string msg = string.Format("保存 {0} 失败", "defaultL9.sub");
				if (LanguageOper.available == true)
				{
					msg = string.Format(LanguageOper.ReadValue(section, "msgStr.6"), "defaultL9.sub");
					;
				}
				Console.WriteLine(ex.Message + ex.StackTrace);
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		// 分控设置 - 更新主界面
		private void reloadL9Interface()
		{
			// 要刷新到界面的字符串
			string updateStr = "";

			// 更新当前芯片名称
			this.cmbChipType.Text = chipName;

			/************************************ 灯具参数 ****************************************/

			// 当三色/四色选择不合法时, 默认选择为三色
			if (!(rvCardL9Config.mainColorMode >= 3) && (rvCardL9Config.mainColorMode <= 4))
			{
				rvCardL9Config.mainColorMode = 3;
			}

			// 规则排列
			if (rvCardL9Config.colorOrderMode == 0)
			{
				regularRadioButton.Checked = true;
				manualRadioButton.Checked = false;
				colorOrderComboBox.Enabled = true;
				manualSetButton.Enabled = false;
                manualRadioJustSelected = false;
			}
			// 任意排列
			else if (rvCardL9Config.colorOrderMode == 1)
			{
				regularRadioButton.Checked = false;
				manualRadioButton.Checked = true;
				colorOrderComboBox.Enabled = false;
				manualSetButton.Enabled = true;
                manualRadioJustSelected = true;
            }

            colorOrderComboBox.Items.Clear();
            var colorOrderList = Tools.getColorOrderList();
            for (var i = 0; i < colorOrderList.Count; i++) {
                colorOrderComboBox.Items.Add(colorOrderList[i]);
            }

            if (rvCardL9Config.colorOrderMode == 0) {
                // 设置颜色模式：三色模式
                rvCardL9Config.mainColorMode = 3;

                if (initDone == true) {
                    // 设置预设的颜色排列选项
                    colorOrderComboBox.SelectedIndex = 0;

                    // 填写 manualColorList
                    rvCardL9Config.SetColorOrder(rvCardL9Config.mainColorMode, colorOrderComboBox.SelectedIndex);

                    // 根据界面配置更新颜色模式和灯具排列
                    updateMapModeAndColorString();
                }
            }

            // 设置预设的颜色排列选项
            colorOrderComboBox.SelectedIndex = rvCardL9Config.rgbwOrder;

			/********************************** END 灯具参数 **************************************/

			/************************************ 分控带载 ****************************************/

			int maxPayload = ZqConfig.ReadValueInt(chipName, "max_payload", m_ChipInfoFileName);
			if (maxPayload * 3 % rvCardL9Config.mainColorMode != 0)
			{
				rvCardL9Config.maxPixelLength = maxPayload * 3 / rvCardL9Config.mainColorMode + 1;
			}
			else
			{
				rvCardL9Config.maxPixelLength = maxPayload * 3 / rvCardL9Config.mainColorMode;
			}

			// 更新最大点数
            maxLampNumLabel.Text = rvCardL9Config.maxPixelLength.ToString();

			// 更新端口带载数
            cmbChannelNum.Text = (rvCardL9Config.pixelLength * 3).ToString();
            
			/********************************** END 分控带载 **************************************/

			/************************************ 性能/效果 ***************************************/

			// 更新主界面时钟频率数组
			reloadClockList();

			// 更新主界面灰度等级
			reloadGrayList();

			// 更新主界面 gamma 值
			updateStr = rvCardL9Config.gamma.ToString();
			UpdateControlText(gammaLabel, updateStr);

			// 更新主界面占空比
			updateStr = (rvCardL9Config.clockDuty * 100).ToString();
			updateStr = updateStr + " %";
			UpdateControlText(clockDutyLabel, updateStr);

			// 更新主界面低灰平滑度
			updateStr = rvCardL9Config.lowGraySmooth.ToString();
			UpdateControlText(lowGraySmoothLabel, updateStr);

			// 更新主界面起灰值
			updateStr = rvCardL9Config.startGray.ToString();
			UpdateControlText(grayStartLabel, updateStr);

			/********************************** END 性能/效果 *************************************/

			// 更新通道电流显示
			if (rvCardL9Config.currentAdjustEnable == 0)
			{
				rvCardL9Config.currentIndexList.Clear();
				rvCardL9Config.currentLevelDefault = 0;
				rvCardL9Config.currentLevelMax = 0;
				rvCardL9Config.currentChannelMax = 0;
				rvCardL9Config.currentAdjustSpecial = 0;
			}

			// 分控是否已设置异形数据
			if (rvCardL9Config.sysControlMode == 0)
			{
				// 标志位 sysControlMode = 0, 勾选 subHasConfigMapDataCheckBox
				subHasConfigMapDataCheckBox.Checked = true;
			}
			else if (rvCardL9Config.sysControlMode == 1)
			{
				// 标志位 sysControlMode = 1, 不勾选 subHasConfigMapDataCheckBox
				subHasConfigMapDataCheckBox.Checked = false;
			}
		}

		// 分控设置 - 刷新主界面芯片名称
		private void showDefaultChipType()
		{
			if (m_MainMenuItemArray.Length == 0)
			{
				return;
			}

			for (int i = 0; i < m_MainMenuItemArray.Length; i++)
			{
				string childStr = ZqConfig.ReadValueString("ChipType", m_MainMenuItemArray[i], m_ChipInfoFileName);
				string[] chipNameArray = childStr.Split(new char[] { '-' });
				for (int j = 0; j < chipNameArray.Length; j++)
				{
					int chipType = ZqConfig.ReadValueInt(chipNameArray[j], "No", m_ChipInfoFileName);
					int subNo = ZqConfig.ReadValueInt(chipNameArray[j], "subNo", m_ChipInfoFileName);
					if (rvCardL9Config.chipType == chipType && rvCardL9Config.subNo == subNo)
					{
						chipName = chipNameArray[j];
						return;
					}
				}
			}
		}

		// 分控设置 - 刷新时钟频率列表
		private void reloadClockList()
		{
			// 获取数组长度
			int clockListLength = ZqConfig.ReadValueInt(chipName, "clockListLength", m_ChipInfoFileName);
			if (clockListLength == 0)
			{
				return;
			}

			// 更新时钟频率数组
			m_ClockList = new string[clockListLength];
			for (int i = 0; i < clockListLength; i++)
			{
				string staticStr = "clockList";
				staticStr = staticStr + i.ToString();
				string clockValue = ZqConfig.ReadValue(chipName, staticStr, m_ChipInfoFileName);
				m_ClockList[i] = clockValue;
			}

			// 获取缺省时钟频率index
			int clockIndex = ZqConfig.ReadValueInt(chipName, "clockListIndex", m_ChipInfoFileName);

			// 更新 L9 保存设置
			List<double> newClockList = new List<double>(m_ClockList.Length);
			for (int i = 0; i < m_ClockList.Length; i++)
			{
				newClockList.Add(Convert.ToDouble(m_ClockList[i]));
			}
			int count = rvCardL9Config.SetClockFreqList(newClockList);

			if (m_LoadClockFromSub == true)
			{
				clockIndex = count;
				m_LoadClockFromSub = false;
			}

			if (clockIndex >= m_ClockList.Length)
			{
				clockIndex = m_ClockList.Length - 1;
			}

			UpdateControlText(clockFreqLabel, m_ClockList[clockIndex] + " MHz");
		}

		// 分控设置 - 刷新灰度等级列表
		private void reloadGrayList()
		{
			// 取得最低灰度等级
			int min_gray = ZqConfig.ReadValueInt(chipName, "grayLevelMin", m_ChipInfoFileName);

			// 取得最高灰度等级
			int max_gray = ZqConfig.ReadValueInt(chipName, "grayLevelMax", m_ChipInfoFileName);

			// 取得默认灰度等级
			int gray_level = ZqConfig.ReadValueInt(chipName, "graylevel", m_ChipInfoFileName);

			// 更新灰度等级数组
			int selection_num = 0;
			int num = 0;

			// 将最大灰度等添加到 list 中
			List<string> grayListStr = new List<string>(20);
			List<int> grayListInt = new List<int>(20);
			int n = Convert.ToInt32(Math.Pow(2, Convert.ToDouble(max_gray)));
			grayListStr.Add(n.ToString());
			grayListInt.Add(n);
			if (gray_level == max_gray)
			{
				selection_num = 0;
			}
			num = 1;
			for (int i = max_gray - min_gray - 1; i >= 0; i--)
			{
				if (i == 0)
				{
					if (gray_level == min_gray)
					{
						selection_num = num;
					}
					n = Convert.ToInt32(Math.Pow(2, Convert.ToDouble(min_gray)));
					grayListStr.Add(n.ToString());
					grayListInt.Add(n);
					break;
				}
				// 取得 ini 文件信息
				string str = "grayLevelList";
				str = str + i.ToString();
				str = ZqConfig.ReadValue(chipName, str, m_ChipInfoFileName);
				if (str == "")
				{
					continue;
				}
				int gray = Convert.ToInt32(str);
				if (gray == gray_level)
				{
					selection_num = num;
				}
				n = Convert.ToInt32(Math.Pow(2, Convert.ToDouble(gray)));
				grayListStr.Add(n.ToString());
				grayListInt.Add(n);
				num++;
			}

			m_GrayList = grayListStr.ToArray();
			string str_default = (Math.Pow(2, (gray_level))).ToString();
			UpdateControlText(grayLevelLabel, str_default);

			// 更新参数设置界面灰度等级列表
			int selection_sub = rvCardL9Config.SetGrayLevelList(grayListInt);

			// 更新 L9 保存信息
			if (m_LoadGrayFromSub)
			{
				rvCardL9Config.SetGrayIndex(selection_num);
				m_LoadGrayFromSub = false;
			}
			else
			{
				if (rvCardL9Config.grayIndexChangedFlag == false)
				{
					for (int i = 0; i < grayListInt.Count; i++)
					{
						if (Convert.ToInt32(Math.Pow(2, selection_sub)) == grayListInt[i])
						{
							rvCardL9Config.SetGrayIndex(i);
						}
					}
				}
			}
		}

		// 分控设置 - 高级设置
		private void proSet_Click(object sender, EventArgs e)
		{
			l9ProSetDlg.Text = chipName + "高级设置";

			/****************** 高级设置界面数据初始化 ******************/

			// 设置时钟频率列表
			l9ProSetDlg.m_ClockList = m_ClockList;
			// 设置时钟频率默认选择 index
			l9ProSetDlg.m_SelectedClockIndex = rvCardL9Config.clockFreqIndex;
			// 设置时钟占空比
			l9ProSetDlg.m_ClockDuty = (rvCardL9Config.clockDuty * 100).ToString();
			// 更新灰度等级列表
			l9ProSetDlg.m_GrayList = m_GrayList;
			// 设置默认灰度等级index
			l9ProSetDlg.m_SelectedGrayIndex = rvCardL9Config.grayLevelIndex;
			// 设置gama值
			l9ProSetDlg.m_Gamma = rvCardL9Config.gamma.ToString();
			// 设置起灰值
			l9ProSetDlg.m_GrayStart = rvCardL9Config.startGray.ToString();
			// 设置低灰平滑度
			l9ProSetDlg.m_LowGraySmooth = rvCardL9Config.lowGraySmooth.ToString();
			// 设置通道亮度-R
			l9ProSetDlg.m_BrightR = rvCardL9Config.brightR;
			// 设置通道亮度-G
			l9ProSetDlg.m_BrightG = rvCardL9Config.brightG;
			// 设置通道亮度-B
			l9ProSetDlg.m_BrightB = rvCardL9Config.brightB;
			// 设置通道亮度-W
			l9ProSetDlg.m_BrightW = rvCardL9Config.brightW;

			// 设置其他参数
			if (rvCardL9Config.powerOnProtect == 1)
			{
				l9ProSetDlg.m_OpenProtect = true;
			}
			else
			{
				l9ProSetDlg.m_OpenProtect = false;
			}

			if (rvCardL9Config.colorReverse == 1)
			{
				l9ProSetDlg.m_ColorRevert = true;
			}
			else
			{
				l9ProSetDlg.m_ColorRevert = false;
			}

			if (rvCardL9Config.receiveCardWidth == 1)
			{
				l9ProSetDlg.m_ReciveWidth = true;
			}
			else
			{
				l9ProSetDlg.m_ReciveWidth = false;
			}

			if (rvCardL9Config.noSignalMode == 1)
			{
				l9ProSetDlg.m_NoSignalShowLastFrame = true;
			}
			else
			{
				l9ProSetDlg.m_NoSignalShowLastFrame = false;
			}

            if (rvCardL9Config.outInvert == 1)
            {
                l9ProSetDlg.m_OutInvert = true;
            }
            else
            {
                l9ProSetDlg.m_OutInvert = false;
            }

			if (rvCardL9Config.persistCP == 1)
			{
				l9ProSetDlg.m_PersistCP = true;
			}
			else
			{
				l9ProSetDlg.m_PersistCP = false;
			}

			l9ProSetDlg.initEnvironment();
			l9ProSetDlg.parent = this;

			this.addForm("Form_ProSet", l9ProSetDlg);
			l9ProSetDlg.setLanguageText();
			DialogResult dr = l9ProSetDlg.ShowDialog();
			this.removeForm("Form_ProSet");

			if (dr == DialogResult.OK)
			{
				m_LoadClockFromSub = true;
				m_LoadGrayFromSub = true;

				// 更新主界面时钟频率
				rvCardL9Config.clockFreqIndex = l9ProSetDlg.m_SelectedClockIndex;
				clockFreqLabel.Text = m_ClockList[l9ProSetDlg.m_SelectedClockIndex] + " MHz";

				// 更新主界面占空比
				rvCardL9Config.clockDuty = Convert.ToDouble(l9ProSetDlg.m_ClockDuty) / 100.0;
				clockDutyLabel.Text = l9ProSetDlg.m_ClockDuty + "%";

				// 更新主界面灰度等级
				rvCardL9Config.SetGrayIndex(l9ProSetDlg.m_SelectedGrayIndex);
				grayLevelLabel.Text = m_GrayList[l9ProSetDlg.m_SelectedGrayIndex];

				// 更新主界面 Gamma 值
				double gammaValue = Convert.ToDouble(l9ProSetDlg.m_Gamma);
				if (gammaValue == 0)
				{
					gammaValue = 2.8;
				}
				else if (gammaValue > 10)
				{
					gammaValue = 10;
				}
				rvCardL9Config.SetGamma(gammaValue);
				gammaLabel.Text = rvCardL9Config.gamma.ToString();

				// 更新主界面起灰值
				int startGray = Convert.ToInt32(l9ProSetDlg.m_GrayStart);
				if (startGray > 255)
				{
					startGray = 255;
				}
				rvCardL9Config.SetGrayStart(startGray);
				grayStartLabel.Text = startGray.ToString();

				// 更新主界面低灰平滑度
				int lowGraySmooth = Convert.ToInt32(l9ProSetDlg.m_LowGraySmooth);
				rvCardL9Config.SetLowGraySmooth(lowGraySmooth);
				lowGraySmoothLabel.Text = lowGraySmooth.ToString();

				// 更新主界面开机渐亮保护状态
				int state = (l9ProSetDlg.m_OpenProtect == false ? 0 : 1);
				rvCardL9Config.powerOnProtect = state;

				// 更新色彩还原
				if (l9ProSetDlg.m_ColorRevert == true)
				{
					rvCardL9Config.colorReverse = 1;
				}
				else
				{
					rvCardL9Config.colorReverse = 0;
				}

				// 更新拓展接收卡截取宽度
				if (l9ProSetDlg.m_ReciveWidth == true)
				{
					rvCardL9Config.receiveCardWidth = 1;
				}
				else
				{
					rvCardL9Config.receiveCardWidth = 0;
				}

				// 更新无信号时显示最后一帧
				if (l9ProSetDlg.m_NoSignalShowLastFrame == true)
				{
					rvCardL9Config.noSignalMode = 1;
				}
				else
				{
					rvCardL9Config.noSignalMode = 0;
				}

				// 更新保持屏体连接和调光调色参数
				if (l9ProSetDlg.m_PersistCP == true)
				{
					rvCardL9Config.persistCP = 1;
				}
				else
				{
					rvCardL9Config.persistCP = 0;
				}

                // 更新输出反向
                if (l9ProSetDlg.m_OutInvert == true)
                {
                    rvCardL9Config.outInvert = 1;
                }
                else
                {
                    rvCardL9Config.outInvert = 0;
                }

				// 判断当前的灰度等级是否<=1024，若<=1024，则禁用颜色还原功能
				int index = l9ProSetDlg.m_SelectedGrayIndex;
				int grayLevel = Convert.ToInt32(m_GrayList[index]);
				if (grayLevel <= 1024)
				{
					rvCardL9Config.colorReverse = 0;
				}

				// 更新通道亮度 - R/G/B/W
				rvCardL9Config.brightR = l9ProSetDlg.m_BrightR;
				rvCardL9Config.brightG = l9ProSetDlg.m_BrightG;
				rvCardL9Config.brightB = l9ProSetDlg.m_BrightB;
				rvCardL9Config.brightW = l9ProSetDlg.m_BrightW;
			}
		}

		// 分控设置 - 更新控件 Text 内容
		private void UpdateControlText(Control control, string str)
		{
			control.Text = str;
		}

		// 分控设置 - 更改灯具参数
		private void loadChip()
		{
			// 设置 menu 显示位置
			// 添加芯片菜单项
			this.contextMenuStrip_Chip = new System.Windows.Forms.ContextMenuStrip();
			string fontName = this.Font.Name;
			contextMenuStrip_Chip.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            this.contextMenuStrip_Chip.Width = cmbChipType.Width;
			ToolStripMenuItem subItem = new ToolStripMenuItem();
			for (int i = 0; i < m_MainMenuItemArray.Length; i++)
			{
				// 添加 1 级菜单项
				subItem = AddContextMenu(m_MainMenuItemArray[i], contextMenuStrip_Chip.Items, null);

				// 读取单个芯片定义
				string sigleChipType = ZqConfig.ReadValueString("ChipType", m_MainMenuItemArray[i], m_ChipInfoFileName);

				// 分割得到单个芯片类型定义
				m_ChildMenuItemArray = sigleChipType.Split(new char[] { '-' });

				// 添加 2 级菜单项
				for (int j = 0; j < m_ChildMenuItemArray.Length; j++)
				{
					AddContextMenu(m_ChildMenuItemArray[j], subItem.DropDownItems, subItem_Click);
				}
			}
            Point pt = new Point(cmbChipType.Location.X, cmbChipType.Location.Y + cmbChipType.Height);
			this.contextMenuStrip_Chip.Show(this.lampParaGroupBox, pt);
			this.BringToFront();
            this.contextMenuStrip_Chip.BringToFront();
		}

		// 分控设置 - 灯具排列设置
		private void manualSetButton_Click(object sender, EventArgs e)
		{
			// 当通道数为 4/8/16 时，若规则排列选择为三色，则高级界面初始化后，应改为三色
			bool change2ThreeColorMode = false;
			if (colorOrderComboBox.Text.Length == 3 && manualRadioJustSelected == false)
			{
				if (rvCardL9Config.channel == 4 || rvCardL9Config.channel == 8 || rvCardL9Config.channel == 16)
				{
					change2ThreeColorMode = true;
				}
				manualRadioJustSelected = false;
			}

			// 灯具排列设置窗体
			Form_ChipSet l9ChipSet = new Form_ChipSet(chipJustChanged, rvCardL9Config.channelManualEnable, change2ThreeColorMode);

			// 设置芯片名称
			l9ChipSet.chipName = chipName;

			if (nflgArray == 0)	// 需要还原芯片个数、管脚数、列映射
			{
				// 芯片个数还原为1
				rvCardL9Config.useChipNum = 1;
				// 还原管脚数和列映射（目前来看不用还原 默认都是三个管脚和三色模式）
			}
			else
			{
				// 恢复芯片管脚排列改变标志
				nflgArray = -1;
			}

			// 设置芯片管脚数
			l9ChipSet.channelNum = rvCardL9Config.channel;

            // 设置芯片个数
            l9ChipSet.chipNum = rvCardL9Config.useChipNum;

            // 设置主颜色模式
            l9ChipSet.mainColorMode = rvCardL9Config.mainColorMode;

            // 设置子颜色模式（四色用）
            l9ChipSet.subColorMode = rvCardL9Config.fourColorMode;

            // 设置手动排列的数据
            byte[] manualColorArray = new byte[512];
            rvCardL9Config.GetManualColorArray(manualColorArray);
            l9ChipSet.setManualColorArray(manualColorArray);

			// 初始化窗体
			l9ChipSet.initForm();

			// 显示芯片输出排列设置窗体
			this.addForm("Form_ChipSet", l9ChipSet);
			l9ChipSet.setLanguageText();
			DialogResult dr = l9ChipSet.ShowDialog();
			this.removeForm("Form_ChipSet");
			
			if (dr == DialogResult.OK)
			{
				rvCardL9Config.channel = l9ChipSet.channelNum;
				rvCardL9Config.useChipNum = l9ChipSet.chipNum;

				l9ChipSet.getManualColorArray(manualColorArray);
				rvCardL9Config.SetManualColorArray(manualColorArray);

				rvCardL9Config.mainColorMode = l9ChipSet.mainColorMode;
				rvCardL9Config.useChipNum = l9ChipSet.chipNum;				// 芯片数量
                if ((userColorType >= 0) && (userColorType != 255))                                     // 四色模式和用户设置匹配
                {
                    rvCardL9Config.fourColorMode = userColorType;
                    defaultColorType = l9ChipSet.subColorMode;
                }
                else
                {
                    rvCardL9Config.fourColorMode = l9ChipSet.subColorMode;
                    defaultColorType = l9ChipSet.subColorMode;
                }

				int maxcount = ZqConfig.ReadValueInt(chipName, "max_payload", m_ChipInfoFileName);
				if (maxcount * 3 % rvCardL9Config.mainColorMode != 0)
				{
					rvCardL9Config.maxPixelLength = Convert.ToInt32(Convert.ToDouble(maxcount * 3) / rvCardL9Config.mainColorMode) + 1;
				}
				else
				{
					rvCardL9Config.maxPixelLength = Convert.ToInt32(Convert.ToDouble(maxcount * 3) / rvCardL9Config.mainColorMode);
				}

				// 更新界面实际点数和最大点数
                maxLampNumLabel.Text = rvCardL9Config.maxPixelLength.ToString();

				if (rvCardL9Config.pixelLength > rvCardL9Config.maxPixelLength)
				{
					rvCardL9Config.pixelLength = rvCardL9Config.maxPixelLength;
					cmbChannelNum.Text = (rvCardL9Config.pixelLength * 3).ToString();
				}
				else
				{
					cmbChannelNum.Text = (rvCardL9Config.pixelLength * 3).ToString();
				}

				// 规则排列
				if (rvCardL9Config.colorOrderMode == 0)
				{
					// 三色模式
					baseCoreNet.setBaseMapMode(MapMode.Baned);

					StringBuilder sb = new StringBuilder();
					byte[] manualColorArrayPara = rvCardL9Config.GetManualColorArray();
					sb.Append(getColorChar(manualColorArrayPara[1]));
					sb.Append(getColorChar(manualColorArrayPara[3]));
					sb.Append(getColorChar(manualColorArrayPara[5]));
					baseCoreNet.setBaseColorString(sb.ToString());

				}
				// 任意排列
				else
				{
					// 三色模式
					if (rvCardL9Config.mainColorMode == 3)
					{
						baseCoreNet.setBaseMapMode(MapMode.Baned);

						StringBuilder sb = new StringBuilder();
						byte[] manualColorArrayPara = rvCardL9Config.GetManualColorArray();
						sb.Append(getColorChar(manualColorArrayPara[1]));
						sb.Append(getColorChar(manualColorArrayPara[3]));
						sb.Append(getColorChar(manualColorArrayPara[5]));
						baseCoreNet.setBaseColorString(sb.ToString());
					}
					// 四色模式
					else if (rvCardL9Config.mainColorMode == 4)
					{
                        // 四色纯模式
                        if (rvCardL9Config.fourColorMode == 1) 
                        {
                            baseCoreNet.setBaseMapMode(MapMode.FourPure);
                        }
                            // 四色增强模式
                        else if (rvCardL9Config.fourColorMode == 2) 
                        {
                            baseCoreNet.setBaseMapMode(MapMode.FourIncrease);
                        }

                        StringBuilder sb = new StringBuilder();
                        byte[] manualColorArrayPara = rvCardL9Config.GetManualColorArray();
                        sb.Append(getColorChar(manualColorArrayPara[1]));
                        sb.Append(getColorChar(manualColorArrayPara[3]));
                        sb.Append(getColorChar(manualColorArrayPara[5]));
                        sb.Append(getColorChar(manualColorArrayPara[7]));
                        baseCoreNet.setBaseColorString(sb.ToString());

                        baseCoreNet.setUserColorType(rvCardL9Config.fourColorMode);
                   }
			}

				// 保存当前配置至 defaultL9.sub
				saveCurrentChipConfig();
			}

			// 根据界面配置更新颜色模式和灯具排列
			updateMapModeAndColorString();
		}

		// 分控设置 - 规则排列无空脚
		private void custRadioButton_CheckedChanged(object sender, EventArgs e)
		{
			if (initDone == false)
			{
				return;
			}
            regularRadioButton2.Checked = regularRadioButton.Checked;
			if (regularRadioButton.Checked == true)
			{
				// 芯片管脚排列模式改变为了规则排列
				nflgArray = 0;

				manualRadioButton.Checked = false;
				manualSetButton.Enabled = false;
				colorOrderComboBox.Enabled = true;

				// 设置颜色排列模式 - 规则排列无空脚
				rvCardL9Config.colorOrderMode = 0;

				//计算颜色排列相关数据
				rvCardL9Config.colorOrderAutoCalculate(chipName, colorOrderComboBox.Text, colorOrderComboBox.SelectedIndex);

				int maxPixelLength = ZqConfig.ReadValueInt(chipName, "max_payload", m_ChipInfoFileName);
				maxPixelLength = Convert.ToInt32(Convert.ToDouble(maxPixelLength * 3) / rvCardL9Config.mainColorMode);
				rvCardL9Config.maxPixelLength = maxPixelLength;

                // 更新界面实际点数和最大点数
                maxLampNumLabel.Text = rvCardL9Config.maxPixelLength.ToString();

                if (rvCardL9Config.pixelLength > rvCardL9Config.maxPixelLength)
                {
                    rvCardL9Config.pixelLength = rvCardL9Config.maxPixelLength;
                    cmbChannelNum.Text = (rvCardL9Config.pixelLength * 3).ToString();
                }
                else
                {
                    cmbChannelNum.Text = (rvCardL9Config.pixelLength * 3).ToString();
                }
			}
			else
			{
				regularRadioButton.Checked = false;
				colorOrderComboBox.Enabled = false;
                manualSetButton.Enabled = true;

				// 设置颜色排列模式 - 任意排列
				rvCardL9Config.colorOrderMode = 1;

				// 填写 manualColorList
				rvCardL9Config.SetColorOrder(rvCardL9Config.mainColorMode, colorOrderComboBox.SelectedIndex);

				// 根据界面配置更新颜色模式和灯具排列
				updateMapModeAndColorString();
			}
		}

		// 分控设置 - 管脚任意排列
		private void manualRadioButton_CheckedChanged(object sender, EventArgs e)
		{
			if (initDone == false)
			{
				return;
			}
            manualRadioButton2.Checked = manualRadioButton.Checked;
			manualRadioJustSelected = true;
		}

		// 分控设置 - 灯具颜色排列
		private void colorOrderComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (initDone == false)
			{
				return;
			}
            
			//计算颜色排列相关数据
			rvCardL9Config.colorOrderAutoCalculate(chipName, colorOrderComboBox.Text, colorOrderComboBox.SelectedIndex);

			// 根据界面配置更新颜色模式和灯具排列
			updateMapModeAndColorString();
		}

		/*********************************************************************/

		// 分控设置 - 应用sub
		public void applySubButtonPerformClick()
		{
			applySubButton.PerformClick();
		}

		// 分控设置 - 测试sub
		public void testSubButtonPerformClick()
		{
			testSubButton.PerformClick();
		}

		// 分控设置 - 分控复位
		public void resetButtonPerformClick()
		{
			//resetSubButton.PerformClick();
		}

        // 分控设置 - 强制停止应用sub
        public void forceStopApplySubButtonPerformClick() {
            //forceStopApplySubButton.PerformClick();
        }

		// 分控设置 - 应用sub
		private void applySubButton_Click(object sender, EventArgs e)
		{
			//rvCardL9Config.SaveToSub("debug.sub", 0x080200);	// for debug
            if (userColorType != 255)
            {
                MessageBox.Show("请将主界面颜色设置恢复为“默认”");
                return;
            }

			if (addrMapDataIsDownloading)
			{
				string msg = "正在下载布线文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.3");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				
				return;
			}

			if (addrMapDataIsClearing)
			{
				string msg = "正在清除布线文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.4");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				
				return;
			}

			SelectedSubInfo selectedSubInfo = new SelectedSubInfo();

			m_FormSelectSub = new Form_SelectSub(selectedSubInfo, baseCoreNet);
			int posX = this.Location.X + (this.Size.Width - m_FormSelectSub.Size.Width) / 2;
			int posY = this.Location.Y + (this.Size.Height - m_FormSelectSub.Size.Height) / 2;
			m_FormSelectSub.Location = new Point(posX, posY);

			this.addForm("Form_SelectSub", m_FormSelectSub);
			m_FormSelectSub.setLanguageText();
			DialogResult dr = m_FormSelectSub.ShowDialog();
			this.removeForm("Form_SelectSub");

			if (dr == DialogResult.OK)
			{
				// 根据界面配置更新颜色模式和灯具排列
				updateMapModeAndColorString();

				// 生成 sub 数据
				byte[] subData = rvCardL9Config.GetSubData();

				// 下发 sub 数据
				bool withSplit1 = (saveSubPosInfoCheckBox.Checked == true ? false : true);	// 勾选：不写 1 区，不勾选：写 1 区
				bool startResult = baseCoreNet.startApplySubSend(subData, selectedSubInfo, selectedSubInfo.overall, withSplit1);

				if (startResult == true)
				{
					subSendApplyOrTest = "apply";
					applySubButton.Enabled = false;
					testSubButton.Enabled = false;
					//resetSubButton.Enabled = false;
					checkSubButton.Enabled = false;
					if (selectedSubInfo.overall == false && selectedSubInfo.targetSubIndexList.Count > 0)
					{
						//forceStopApplySubButton.Enabled = true;
					}

					if (l9ProSetDlg.Visible == true)
					{
						l9ProSetDlg.BeginInvoke(l9ProSetDlg.setSubSendButtonEnableDelegate, false);
					}

					subDataIsDownloading = true;
				}
			}
		}

		// 分控设置 - 下发测试sub
        private bool testSub(SelectedSubInfo selectedSubInfo)
        {
            if (this.InvokeRequired)
            {
                bool res = false;
                this.Invoke(new MethodInvoker(delegate()
                {
                    res = this.testSub(selectedSubInfo);
                }));
                return res;
            }
            else
            {
                // 根据界面配置更新颜色模式和灯具排列
                updateMapModeAndColorString();

                // 生成 sub 数据
                byte[] subData = rvCardL9Config.GetSubData();

                // 下发 sub 数据
                bool withSplit1 = (saveSubPosInfoCheckBox.Checked == true ? false : true);	// 勾选：不写 1 区，不勾选：写 1 区
                bool res = baseCoreNet.startTestSubSend(subData, selectedSubInfo, selectedSubInfo.overall, withSplit1);

                return res;
            }
        }

        // 分控设置 - 测试sub
		private void testSubButton_Click(object sender, EventArgs e)
		{
            if (addrMapDataIsDownloading)
            {
                string msg = "正在下载布线文件，请先停止操作";
                if (LanguageOper.available == true)
                {
                    msg = LanguageOper.ReadValue(section, "msgStr.3");
                }
                MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);

                return;
            }

            if (addrMapDataIsClearing)
            {
                string msg = "正在清除布线文件，请先停止操作";
                if (LanguageOper.available == true)
                {
                    msg = LanguageOper.ReadValue(section, "msgStr.4");
                }
                MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);

                return;
            }

            SelectedSubInfo selectedSubInfo = new SelectedSubInfo();

            m_FormSelectSub = new Form_SelectSub(selectedSubInfo, baseCoreNet);
            int posX = this.Location.X + (this.Size.Width - m_FormSelectSub.Size.Width) / 2;
            int posY = this.Location.Y + (this.Size.Height - m_FormSelectSub.Size.Height) / 2;
            m_FormSelectSub.Location = new Point(posX, posY);

            this.addForm("Form_SelectSub", m_FormSelectSub);
            m_FormSelectSub.setLanguageText();
            DialogResult dr = m_FormSelectSub.ShowDialog();
            this.removeForm("Form_SelectSub");

            if (dr == DialogResult.OK)
            {
                bool res = testSub(selectedSubInfo);
                if (res == true)
                {
                    subSendApplyOrTest = "test";
                    applySubButton.Enabled = false;
                    testSubButton.Enabled = false;
                    //resetSubButton.Enabled = false;
                    checkSubButton.Enabled = false;
                    if (l9ProSetDlg.Visible == true)
                    {
                        l9ProSetDlg.BeginInvoke(l9ProSetDlg.setSubSendButtonEnableDelegate, false);
                    }
                }
            }
		}

		// 分控设置 - 强制停止应用sub
		private void forceStopApplySubButton_Click(object sender, EventArgs e)
		{
			baseCoreNet.setPauseDownloadSub(true);
			string msg = "确认停止下载 sub 文件吗？";
			if (LanguageOper.available == true)
			{
				msg = LanguageOper.ReadValue(section, "msgStr.29");
			}
			DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
			if (dr == System.Windows.Forms.DialogResult.OK)
			{
				baseCoreNet.setForceStopDownloadSub(true);
				baseCoreNet.setPauseDownloadSub(false);
			}
			else
			{
				baseCoreNet.setForceStopDownloadSub(false);
				baseCoreNet.setPauseDownloadSub(false);
			}
		}

		// 分控设置 - 分控复位
		private void resetButton_Click(object sender, EventArgs e)
		{
			if (subDataIsDownloading)
			{
				string msg = "正在下载 sub 文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.5");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				
				return;
			}

			if (addrMapDataIsDownloading)
			{
				string msg = "正在下载布线文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.3");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				
				return;
			}

			if (addrMapDataIsClearing)
			{
				string msg = "正在清除布线文件，请先停止操作";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.4");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				
				return;
			}

			SelectedSubInfo selectedSubInfo = new SelectedSubInfo();
			m_FormSelectSub = new Form_SelectSub(selectedSubInfo, baseCoreNet, "reset");
			int posX = this.Location.X + (this.Size.Width - m_FormSelectSub.Size.Width) / 2;
			int posY = this.Location.Y + (this.Size.Height - m_FormSelectSub.Size.Height) / 2;
			m_FormSelectSub.Location = new Point(posX, posY);

			this.addForm("Form_SelectSub", m_FormSelectSub);
			m_FormSelectSub.setLanguageText();
			DialogResult dr = m_FormSelectSub.ShowDialog();
			this.removeForm("Form_SelectSub");

			if (dr == DialogResult.OK)
			{
				applySubButton.Enabled = false;
				testSubButton.Enabled = false;
				checkSubButton.Enabled = false;
				
				Thread resetThread = new Thread(() =>
				{
					// 硬件配置操作前处理
					baseCoreNet.configPreTreat();

					// 主逻辑动作
					resetSubCtrl(selectedSubInfo);

					// 硬件配置操作后处理
					baseCoreNet.configPostTreat();
				});
				resetThread.IsBackground = true;
				resetThread.Start();
			}
		}

		// 分控设置 - 校验分控
		private void checkSubButton_Click(object sender, EventArgs e)
		{
			Form_CheckSubData checkSubDataForm = new Form_CheckSubData(baseCoreNet, rvCardL9Config.GetSubData());
			this.addForm("Form_CheckSubData", checkSubDataForm);
			checkSubDataForm.setLanguageText();
			checkSubDataForm.ShowDialog();
			this.removeForm("Form_CheckSubData");
		}

		// 分控设置 - 配置文件 - 显示菜单
		private void loadSubButton_Click(object sender, EventArgs e)
		{
			// 设置 menu 显示位置
			this.contextMenuStrip_Sub = new System.Windows.Forms.ContextMenuStrip();
			string fontName = this.Font.Name;
			contextMenuStrip_Sub.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
			AddContextMenu("打开", contextMenuStrip_Sub.Items, openSub_Click);
			AddContextMenu("保存", contextMenuStrip_Sub.Items, saveToSub_Click);
			AddContextMenu("另存", contextMenuStrip_Sub.Items, otherSaveToSub_Click);
			if (LanguageOper.available == true)
			{
				contextMenuStrip_Sub.Items[0].Text = LanguageOper.ReadValue(section, "contextSub.ItemsText.0");
				contextMenuStrip_Sub.Items[1].Text = LanguageOper.ReadValue(section, "contextSub.ItemsText.1");
				contextMenuStrip_Sub.Items[2].Text = LanguageOper.ReadValue(section, "contextSub.ItemsText.2");
			}
			Point pt = new Point(loadSubButton.Location.X, loadSubButton.Location.Y + loadSubButton.Height);
			this.contextMenuStrip_Sub.Show(subConfigGroupBox, pt);
			this.BringToFront();
		}

		// 分控设置 - 配置文件 - 打开
		private void openSub_Click(object sender, EventArgs e)
		{
			// 保存当前配置至 defaultL9.sub
			saveCurrentChipConfig();

			// 打开用户指定的 sub 文件
			OpenFileDialog o = new OpenFileDialog();
			o.Filter = "Sub Files(*.sub)|*.sub";
			o.Multiselect = false;
			if (Directory.Exists(lastPath_SubFileConfig))
			{
				o.InitialDirectory = lastPath_SubFileConfig;
			}
			else
			{
				o.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
			}
			if (o.ShowDialog() == DialogResult.OK)
			{
				lastPath_SubFileConfig = (new FileInfo(o.FileName)).DirectoryName;

				string userFileName = o.FileName;
				m_LoadGrayFromSub = true;
				m_LoadClockFromSub = true;

				// 从 sub 文件中读取配置信息
				loadFromSub(userFileName);

				// 更新主界面芯片名称
				showDefaultChipType();

				// 初始化分控设置界面信息
				initChipSetTab();

				// 更改界面显示的分控配置文件路径
				subFileNameTextBox.Text = userFileName;
				subFileNameTextBox.SelectionStart = subFileNameTextBox.Text.Length;
				subFileNameTextBox.ScrollToCaret();

				// 启用 保存/另存 按钮
				contextMenuStrip_Sub.Items[1].Enabled = true;	// 保存
				contextMenuStrip_Sub.Items[2].Enabled = true;	// 另存

				string msg = "Sub文件打开成功";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.30");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			}
		}

		// 分控设置 - 配置文件 - 保存
		private void saveToSub_Click(object sender, EventArgs e)
		{
			if (!subFileNameTextBox.Text.Equals(""))
			{
				// 保存当前配置至 defaultL9.sub
				saveCurrentChipConfig();

				// 保存当前配置至用户文件
				string userFileName = subFileNameTextBox.Text;
				if (!userFileName.Equals(""))
				{
					// 更新用户 sub 文件
					rvCardL9Config.SaveToSub(userFileName, 0x080200);

					// 更新配置文件信息
					if (ZqConfig.IsFileExist(config2012Ini))
					{
						ZqConfig.WriteValue("SUBPath", userFileName, "SUBL9", config2012Ini);
					}

					// 更改界面显示的分控配置文件路径
					subFileNameTextBox.Text = userFileName;
					subFileNameTextBox.SelectionStart = subFileNameTextBox.Text.Length;
					subFileNameTextBox.ScrollToCaret();

					string msg = string.Format("文件保存成功");
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.31"), userFileName);
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				}
			}
		}

		// 分控设置 - 配置文件 - 另存
		private void otherSaveToSub_Click(object sender, EventArgs e)
		{
			// 保存当前配置至 defaultL9.sub
			saveCurrentChipConfig();

			// 保存当前配置至用户文件
			SaveFileDialog s = new SaveFileDialog();
			s.Filter = "Sub Files(*.sub)|*.sub";
			s.FilterIndex = 1;
			s.FileName = subFileNameTextBox.Text;
			if (s.ShowDialog() == DialogResult.OK)
			{
				string userFileName = s.FileName;

				// 更新用户 sub 文件
				rvCardL9Config.SaveToSub(userFileName, 0x080200);

				// 更新配置文件信息
				if (ZqConfig.IsFileExist(config2012Ini))
				{
					ZqConfig.WriteValue("SUBPath", userFileName, "SUBL9", config2012Ini);
				}

				// 更改界面显示的分控配置文件路径
				subFileNameTextBox.Text = userFileName;
				subFileNameTextBox.SelectionStart = subFileNameTextBox.Text.Length;
				subFileNameTextBox.ScrollToCaret();

				string msg = string.Format("文件保存成功");
				if (LanguageOper.available == true)
				{
					msg = string.Format(LanguageOper.ReadValue(section, "msgStr.31"), userFileName);
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);

				contextMenuStrip_Sub.Items[1].Enabled = true;	// 使能保存按钮
			}
		}

		/*********************************************************************/

		// 分控设置 - 复位
		private void resetSubCtrl(SelectedSubInfo selectedSubInfo)
		{
			if (baseCoreNet == null)
			{
				return;
			}

			int activeNetDevIndex = baseCoreNet.getActiveDevIndex();
			if (activeNetDevIndex == -1)
			{
				return;
			}

			byte[] dataBuff = new byte[256];
			for (int i = 0; i < 256; i++)
			{
				dataBuff[i] = 0x0;
			}

			if (selectedSubInfo.overall == false)
			{
				// 发送定点复位命令
				for (int i = 0; i < selectedSubInfo.targetSubIndexList.Count; i++)
				{
					int subIndex = selectedSubInfo.targetSubIndexList[i];
					baseCoreNet.writeSubMem(activeNetDevIndex, subIndex, 0x10000000, dataBuff, false);
				}
			}
			else
			{
				// 发送全局复位命令
				baseCoreNet.writeSubMem(activeNetDevIndex, 0, 0x10000000, dataBuff, true);
			}

			ResetSubDoneEvent(this, new EventArgs());
		}

		// 分控设置 - 根据界面配置更新颜色模式和灯具排列
        private void updateMapModeAndColorString() {
            if (regularRadioButton.Checked){	// 规则排列无空脚
                baseCoreNet.changeMapModeAndColorString(MapMode.Baned, colorOrderComboBox.Text.ToString());
            } else {
                byte[] byteData = rvCardL9Config.GetManualColorArray();
                StringBuilder csb = new StringBuilder();
                csb.Append(getColorChar(byteData[1]));
                csb.Append(getColorChar(byteData[3]));
                csb.Append(getColorChar(byteData[5]));
                csb.Append(getColorChar(byteData[7]));
            }
        }

		// 【调试用】分控设置 - 查看内部颜色数组
		private void viewManualColorListButton_Click(object sender, EventArgs e)
		{
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < 512; i++)
			{
				sb.Append("," + rvCardL9Config.manualColorList[i]);
			}
			MessageBoxEx.Show(this, sb.ToString().Substring(1), tip, MessageBoxButtons.OK, MessageBoxIcon.None);
		}

		// 分控设置 - 事件处理器：分控复位完成
		private void resetSubDoneEventHandler(object source, EventArgs args)
		{
			string msg = "";
			if (LanguageOper.available == true)
			{
				msg = LanguageOper.ReadValue(section, "msgStr.32");
			}
			
			this.Invoke(showTipMessageDelegate, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
			
			applySubButton.Enabled = true;
			testSubButton.Enabled = true;
			checkSubButton.Enabled = true;
		}

		// 分控设置 - 事件处理器：有分控的总包数或错包数达到最大
		private void reachMaxPacketNumEventHandler(object source, EventArgs args)
		{
			// 发送全局清零命令
			baseCoreNet.sendClearPacketCommand(baseCoreNet.getActiveDevIndex());
		}

		// 分控设置 - 分控已设置异形数据
		private void subHasConfigMapDataCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			// 勾选，RVCardL9Config 标志位 sysControlMode = 0
			if (subHasConfigMapDataCheckBox.Checked == true)
			{
				setConfigValue(agentIni, "subHasSetAddrMap", "true");
				rvCardL9Config.SetSysControlMode(0);
			}
			// 不勾选，RVCardL9Config 标志位 sysControlMode = 1
			else
			{
				setConfigValue(agentIni, "subHasSetAddrMap", "false");
				rvCardL9Config.SetSysControlMode(1);
			}
		}

		// 分控设置 - 保存分控位置信息
		private void saveSubPosInfoCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			if (saveSubPosInfoCheckBox.Checked == true)
			{
				setConfigValue(agentIni, "saveSubPosition", "true");
			}
			else
			{
				setConfigValue(agentIni, "saveSubPosition", "false");
			}
		}

        private void btnArtNetTool_Click(object sender, EventArgs e) {
            var form = new Form_ArtNetTool(baseCoreNet);
            form.ShowDialog();
        }

		#endregion

		#region Tab 主控制器 - 业务逻辑
		#endregion

		#region Tab 其他 - 业务逻辑

		/********************************** 灯具写址 *****************************************/

		// 其他 - 灯具写址 - 切换芯片类型
		private void dmxTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
            //if (initDone == false)
            //{
            //    return;
            //}

            var selIndex = dmxTypeComboBox.SelectedIndex;

			if (selIndex == 0)
			{
				// 不支持
				dmxFirstTubeNoLabel.Enabled = false;
				dmxTubeChannelLabel.Enabled = false;
				dmxFirstAddrLabel.Enabled = false;
				lightIndexTextBox.Enabled = false;
				lightChannelTextBox.Enabled = false;
				dmxStartAddrTextBox.Enabled = false;
				dmxSaveButton.Enabled = false;
				dmxClearButton.Enabled = false;
				writeSameAddrCheckBox.Enabled = false;
                writeAddrProButton.Enabled = false;
                writeSameAddrCheckBox.Visible = false;
                EffectTypeComboList.Visible = false;
                EffectLabel.Visible = false;
                lblFirstChan.Visible = false;
                cmbFirstChan.Visible = false;
                btnChipConfig.Visible = false;
                btnChipCurrent.Visible = false;
                btnSelfChan.Visible = false;
			}
			else
			{
				dmxFirstTubeNoLabel.Enabled = true;
				dmxTubeChannelLabel.Enabled = true;
				dmxFirstAddrLabel.Enabled = true;
				lightIndexTextBox.Enabled = true;
				lightChannelTextBox.Enabled = true;
				dmxStartAddrTextBox.Enabled = true;
				dmxSaveButton.Enabled = true;
				dmxClearButton.Enabled = true;
				writeSameAddrCheckBox.Enabled = true;
				writeAddrProButton.Enabled = true;
                writeSameAddrCheckBox.Visible = false;
                EffectTypeComboList.Visible = false;
                EffectLabel.Visible = false;
                lblFirstChan.Visible = false;
                cmbFirstChan.Visible = false;
                usePin4CheckBox.Checked = false;
                usePin4CheckBox.Visible = false;
                btnChipConfig.Visible = false;
                btnChipCurrent.Visible = false;
                btnSelfChan.Visible = false;
                
				if (selIndex == 1)
				{
					// 智彩
                    writeAddrProButton.Visible = false;
                    dmxClearButton.Visible = true;
                    dmxClearButton.Location = new Point(dmxSaveButton.Left, dmxSaveButton.Top + dmxSaveButton.Height + BUTTON_GAP);
                    lightChannelTextBox.Enabled = false;
                    writeSameAddrCheckBox.Visible = true;
                    writeSameAddrCheckBox.Location = lblDmxPos.Location;
				}
				else //if (selIndex == 2 || selIndex == 3)
				{
                    writeAddrProButton.Visible = true;
                    dmxClearButton.Visible = false;
                    writeAddrProButton.Location = new Point(dmxSaveButton.Left, dmxSaveButton.Top + dmxSaveButton.Height + BUTTON_GAP);
                    if (selIndex == 4) { // 效果设置
                        EffectTypeComboList.Visible = true;
                        EffectLabel.Visible = true;
                        EffectTypeComboList.SelectedIndex = 0;
                        lblFirstChan.Visible = true;
                        cmbFirstChan.Visible = true;
                        cmbFirstChan.SelectedIndex = 0;
                    } else if (selIndex == 2 || selIndex == 5) { // 使用 pin4 为写址线
                        // UCS512A/TM512 或 ZD512
                        usePin4CheckBox.Location = lblDmxPos.Location;
                        usePin4CheckBox.Checked = false;
                        usePin4CheckBox.Visible = true;
                    } else if (selIndex >= 6 && selIndex <= 8) { //UCS512D,UCS512E,SM17500 配置参数、电流
                        btnChipConfig.Size = btnChipCurrent.Size = dmxSaveButton.Size;
                        btnChipConfig.Location = new Point(dmxSaveButton.Left - dmxSaveButton.Width - BUTTON_GAP, dmxSaveButton.Top);
                        btnChipCurrent.Location = new Point(btnChipConfig.Left, btnChipConfig.Top + btnChipConfig.Height + BUTTON_GAP);
                        btnChipCurrent.Visible = true;
                        btnChipConfig.Visible = true;
                        if (selIndex >= 7 && selIndex <= 8) { //UCS512E,SM17500 配置自通道
                            btnSelfChan.Size = dmxSaveButton.Size;
                            btnSelfChan.Location = new Point(btnChipCurrent.Left, btnChipCurrent.Top + btnChipCurrent.Height + BUTTON_GAP);
                            btnSelfChan.Visible = true;
                        }
                    }
				}
                

                // 效果设置
			}
		}

		// 其他 - 灯具编号变化 - 自动计算 DMX 首地址
		private void lightIndexTextBox_TextChanged(object sender, EventArgs e)
		{
			if (initDone == false)
			{
				return;
			}
			else
			{
				calcDMXAddr();
			}
		}

		// 其他 - 灯具通道数变化 - 自动计算 DMX 首地址
		private void lightChannelTextBox_TextChanged(object sender, EventArgs e)
		{
			if (initDone == false)
			{
				return;
			}
			else
			{
				calcDMXAddr();
			}
		}

		// 其他 - 计算 DMX 首地址
		private bool calcDMXAddr()
		{
			int lightIndex = -1;
			int lightChannel = -1;
			bool parseRes1 = int.TryParse(lightIndexTextBox.Text.Trim(), out lightIndex);
			bool parseRes2 = int.TryParse(lightChannelTextBox.Text.Trim(), out lightChannel);
			
			if (parseRes1 == false || lightIndex < 1 || lightIndex > 3584)
			{
				string msg = "灯具编号输入错误，应为 [1,3584] 之间的整数";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.33");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				lightIndexTextBox.SelectAll();
				return false;
			}
			else if (parseRes2 == false || lightChannel < 1 || lightChannel > 256)
			{
				string msg = "灯具通道数输入错误，应为 [1,256] 之间的整数";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.34");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				lightChannelTextBox.SelectAll();
				return false;
			}
			else
			{
				int addr = (lightIndex - 1) * lightChannel + 1;	// DMX首地址 = （灯具编号 - 1） * 灯具通道数 + 1

				if (addr > 4096)
				{
					string msg = "DMX首地址超出范围, 应为 [1,4096] 之间的整数";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.35");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					dmxStartAddrTextBox.Text = addr.ToString();
					dmxStartAddrTextBox.SelectAll();
					return false;
				}

				dmxStartAddrTextBox.Text = addr.ToString();
				return true;
			}
		}

		// 其他 - 写入地址
		private void dmxSaveButton_Click(object sender, EventArgs e)
		{
            if (!AddrWriteTag)
            {
                AddrWriteTag = true;
            }
			// 防止重入
			if (dmxSetting == true)
			{
				return;
			}
			else
			{
				dmxSetting = true;
			}

			// 检查特定参数合法性
			int lightIndex = -1;
			int lightChannel = -1;
			bool parseRes1 = int.TryParse(lightIndexTextBox.Text.Trim(), out lightIndex);
			bool parseRes2 = int.TryParse(lightChannelTextBox.Text.Trim(), out lightChannel);
			if (parseRes1 == false || lightIndex < 1 || lightIndex > 3584)
			{
				string msg = "灯具编号输入错误，应为 [1,3584] 之间的整数";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.33");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				lightIndexTextBox.SelectAll();
				dmxSetting = false;
				return;
			}
			else if (parseRes2 == false || lightChannel < 1 || lightChannel > 256)
			{
				string msg = "灯具通道数输入错误，应为 [1,256] 之间的整数";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.34");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				lightChannelTextBox.SelectAll();
				dmxSetting = false;
				return;
			}

			// 检查手动输入的 DMX 首地址
			int dmxStartAddr = 0;
			bool parseRes3 = int.TryParse(dmxStartAddrTextBox.Text.Trim(), out dmxStartAddr);
			if (parseRes3 == false)
			{
				string msg = "DMX首地址不正确";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.36");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				dmxStartAddrTextBox.SelectAll();
				dmxSetting = false;
				return;
			}
			else if (dmxStartAddr != (lightIndex - 1) * lightChannel + 1)
			{
				string msg = "输入的 DMX 地址不符合当前 DMX 编址规则, 仍要写入吗？";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.37");
				}
				DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
				if (dr == DialogResult.No)
				{
					dmxSetting = false;
					return;
				}
			}

			// 检查 DMX 首地址范围
			if (dmxStartAddr > 4096)
			{
				string msg = "DMX首地址超出范围, 应为 [1,4096] 之间的整数";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.35");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				dmxStartAddrTextBox.SelectAll();
				dmxSetting = false;
				return;
			}

			// 收集通用参数 startSubIndex、endSubIndex
			List<ControlNode> nodeList = baseCoreNet.getControlNodeList();
			int totalSubCtrlNum = nodeList == null ? 0 : nodeList.Count;
			SelectedSubInfo selectedSubInfo = new SelectedSubInfo();
            m_FormSelectSub = new Form_SelectSub(selectedSubInfo, baseCoreNet, true);
			//m_FormSelectSub.SetOverallOnly();
			int posX = this.Location.X + (this.Size.Width - m_FormSelectSub.Size.Width) / 2;
			int posY = this.Location.Y + (this.Size.Height - m_FormSelectSub.Size.Height) / 2;
			m_FormSelectSub.Location = new Point(posX, posY);

			this.addForm("Form_SelectSub", m_FormSelectSub);
			m_FormSelectSub.setLanguageText();
			DialogResult subDr = m_FormSelectSub.ShowDialog();
            // 临时代码 - 处理某几个分控或某几个端口
            int selectMode = m_FormSelectSub.selectMode;
            int startSub = m_FormSelectSub.startSub;
            int endSub = m_FormSelectSub.endSub;
            int startPort = m_FormSelectSub.startPort;
            int endPort = m_FormSelectSub.endPort;
			this.removeForm("Form_SelectSub");

			int startSubIndex = selectedSubInfo.startIndex;
			int endSubIndex = selectedSubInfo.endIndex;

			bool overall = selectedSubInfo.overall;		// TODO: 目前仅支持分控全局操作

			// 逻辑动作
			if (subDr == DialogResult.OK)
			{
                var selIndex = dmxTypeComboBox.SelectedIndex;
				if (selIndex == 0)
				{
					// 不支持
					dmxSetting = false;
					return;
				}

				// 收集特定参数
				int writeSameAddr = (writeSameAddrCheckBox.Checked ? 1 : 0);	// 写同地址
				int sub_index = 0;						// 分控全局操作
				int sub_port = 0;						// 端口全局操作
				int rec_index = -1;						// 子控全局操作
				bool usePin4 = usePin4CheckBox.Checked;	// 使用 pin4 为写址线

				if (overall == true)
				{
					// 参数初始值即为全局操作
				}
				else
				{
					// TODO: 目前仅支持分控全局操作
                    //string msg = "目前仅支持分控全局操作";
                    //if (LanguageOper.available == true)
                    //{
                    //    msg = LanguageOper.ReadValue(section, "msgStr.38");
                    //}
                    //MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
                    //dmxSetting = false;
                    //return;
				}

				if (selIndex == 1)
				{
					// 智彩灯具写址
					dmxGroupBox.Enabled = false;
					Thread t = new Thread(() =>
					{
						try
						{
							// 硬件配置操作前处理
							baseCoreNet.configPreTreat();

							// 主逻辑操作
                            if (selectMode == 0)
                            {
                                setMcuSaveDmxStartAddr(sub_index, sub_port, rec_index, dmxStartAddr, writeSameAddr);
                            }
                            else if (selectMode == 1)
                            {
                                for (sub_index = startSub; sub_index <= endSub; sub_index++)
                                {
                                    setMcuSaveDmxStartAddr(sub_index, sub_port, rec_index, dmxStartAddr, writeSameAddr);
                                }
                            }
                            else if (selectMode == 2)
                            {
                                sub_index = startSub;
                                for (sub_port = startPort; sub_port <= endPort; sub_port++)
                                {
                                    setMcuSaveDmxStartAddr(sub_index, sub_port, rec_index, dmxStartAddr, writeSameAddr);
                                }
                            }
                            
							DmxAddrOperDoneEvent(this, new DmxAddrOperEventArgs("saveAddr", true));

							// 硬件配置操作后处理
							baseCoreNet.configPostTreat();
						}
						catch (Exception ex)
						{
							Console.WriteLine(ex.Message + ex.StackTrace);
							DmxAddrOperDoneEvent(this, new DmxAddrOperEventArgs("saveAddr", false));
						}
						finally
						{
							dmxSetting = false;
						}
					});
					t.IsBackground = true;
					t.Start();
                } else if (selIndex >= 2) {
					// DMX写址
					string msg = string.Format("本操作将总线上所有芯片以 <{0}> 为地址重新自动编址, 是否执行此操作？", dmxStartAddr);
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.39"), dmxStartAddr);
					}
					string message = msg;

                    string headTip = tip;
					string innerStr0 = "联芯科/明微灯具写址";
					string innerStr1 = "ZD512-LP灯具写址";
					if (LanguageOper.available == true)
					{
						innerStr0 = LanguageOper.ReadValue(section, "innerStr.0");
						innerStr1 = LanguageOper.ReadValue(section, "innerStr.1");
					}

                    switch (selIndex) {
                        case 2:
                            headTip = innerStr0;
                            break;
                        case 3:
                            headTip = innerStr1;
                            break;
                        default:
                            headTip = tip;
                            break;
                    }
                    

					int dmx_w_type;
					switch (selIndex)
					{
						case 2:
							dmx_w_type = 0;
							break;
						case 3:
							dmx_w_type = 1;
							break;
						case 4:
							dmx_w_type = 2;
                            int effecttype = EffectTypeComboList.SelectedIndex << 1 | cmbFirstChan.SelectedIndex;
                            dmx_w_type |= (effecttype & 0xff) << 8;
							break;
						case 5:
							dmx_w_type = 0;
							break;
                        case 6:
                            dmx_w_type = 3;
                            if (writeAddrMode == 1) {
                                dmx_w_type = 256;
                            } else if (writeAddrMode == 2) {
                                dmx_w_type = 257;
                            }
                            break;
                        case 7:
                            dmx_w_type = 5;
                            if (writeAddrMode == 1) {
                                dmx_w_type = 258;
                            } else if (writeAddrMode == 2) {
                                dmx_w_type = 259;
                            } else if (writeAddrMode == 3) {
                                dmx_w_type = 260;
                            }
                            break;
                        case 8:
                            dmx_w_type = 4;
                            if (writeAddrMode == 1) {
                                dmx_w_type = 261;
                            } else if (writeAddrMode == 2) {
                                dmx_w_type = 262;
                            } else if (writeAddrMode == 3) {
                                dmx_w_type = 263;
                            }
                            break;
						default:
							dmx_w_type = 0;
							break;
					}

					DialogResult dr = MessageBoxEx.Show(this, message, headTip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
					if (dr == System.Windows.Forms.DialogResult.OK)
					{
						dmxGroupBox.Enabled = false;
						Thread t = new Thread(() =>
						{
							try
							{
								// 硬件配置操作前处理
								baseCoreNet.configPreTreat();

								// 主逻辑操作
                                if (selectMode == 0)
                                {
                                    writeSubDmxStartAddr(sub_index, lightChannel, dmxStartAddr, dmx_w_type, usePin4, chipConfig1, chipConfig2);
                                } 
                                else if (selectMode == 1)
                                {
                                    for (sub_index = startSub; sub_index <= endSub; sub_index++)
                                    {
                                        writeSubDmxStartAddr(sub_index, lightChannel, dmxStartAddr, dmx_w_type, usePin4, chipConfig1, chipConfig2);
                                    }
                                }
                                else if (selectMode == 2)
                                {
                                    sub_index = startSub;
                                    uint portmask = 0;
                                    for (sub_port = startPort; sub_port <= endPort; sub_port++)
                                    {
                                        var offset = sub_port - 1;
                                        portmask |= (uint)(1 << offset);
                                    }
                                    writeSubDmxStartAddr(sub_index, lightChannel, dmxStartAddr, dmx_w_type, usePin4, chipConfig1, chipConfig2, portmask);
                                }
								DmxAddrOperDoneEvent(this, new DmxAddrOperEventArgs("saveAddr", true));

								// 硬件配置操作后处理
								baseCoreNet.configPostTreat();
							}
							catch (Exception ex)
							{
								Console.WriteLine(ex.Message + ex.StackTrace);
								DmxAddrOperDoneEvent(this, new DmxAddrOperEventArgs("saveAddr", false));
							}
							finally
							{
								dmxSetting = false;
							}
						});
						t.IsBackground = true;
						t.Start();
					}
				}
			}

			dmxSetting = false;
			return;
		}

		// 其他 - 重置地址 - 仅用于智彩灯具
		private void dmxClearButton_Click(object sender, EventArgs e)
		{
			// 非智彩灯具
			if (dmxTypeComboBox.SelectedIndex != 1)
			{
				return;
			}

			// 防止重入
			if (dmxSetting == true)
			{
				return;
			}
			else
			{
				dmxSetting = true;
			}

			string msg = "是否确认重置地址？";
			if (LanguageOper.available == true)
			{
				msg = LanguageOper.ReadValue(section, "msgStr.41");
			}
			DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

			if (dr == DialogResult.OK)
			{
				// 收集通用参数
				int sub_index = 0;				// 分控全局操作
				int sub_port = 0;				// 端口全局操作
				int rec_index = -1;				// 子控全局操作

				// 智彩灯具 - 清除 DMX 地址
				dmxGroupBox.Enabled = false;
				Thread t = new Thread(() =>
				{
					try
					{
						// 硬件配置操作前处理
						baseCoreNet.configPreTreat();

						// 主逻辑操作
						setMcuClearDmxStartAddr(sub_index, sub_port, rec_index, 0x2E);
						DmxAddrOperDoneEvent(this, new DmxAddrOperEventArgs("clearAddr", true));

						// 硬件配置操作后处理
						baseCoreNet.configPostTreat();
					}
					catch (Exception ex)
					{
						Console.WriteLine(ex.Message + ex.StackTrace);
						DmxAddrOperDoneEvent(this, new DmxAddrOperEventArgs("clearAddr", false));
					}
					finally
					{
						dmxSetting = false;
					}
				});
				t.IsBackground = true;
				t.Start();
			}

			dmxSetting = false;
			return;
		}

		// 其他 - 智彩灯具 - 写址
		public void setMcuSaveDmxStartAddr(int sub_index, int sub_port, int rec_index, int dmx_addr, int writeSameAddr)
		{
			// 获取解码器控制权
			baseCoreNet.setControlState(sub_index, true, false);
			Thread.Sleep(300);

			// 写地址前打开解码器级联写址功能
			baseCoreNet.setMcuOpenAddr(sub_index, sub_port, rec_index, 1);
			Thread.Sleep(2000);

			// 保存 DMX 首地址
			baseCoreNet.setMcuSaveDMXAddr(sub_index, sub_port, rec_index, dmx_addr, writeSameAddr);

			// 解除解码器控制权
			baseCoreNet.setControlState(sub_index, false, false);
			Thread.Sleep(300);
		}

		// 其他 - 智彩灯具 - 清除地址
		public void setMcuClearDmxStartAddr(int sub_index, int sub_port, int rec_index, byte addr)
		{
			// 获取解码器控制权
			baseCoreNet.setControlState(sub_index, true, false);
			Thread.Sleep(300);

			baseCoreNet.setMcuDelMode(sub_index, sub_port, rec_index, addr);

			// 解除解码器控制权
			baseCoreNet.setControlState(sub_index, false, false);
			Thread.Sleep(300);
		}

		// 其他 - 联芯科/明微灯具 - 写址、ZD512-LP灯具写址
        public void writeSubDmxStartAddr(int subIndex, int channelNum, int startAddr, int dmx_w_type, bool usePin4, byte[] config, byte[] current, uint PortMask = 0)
		{
            baseCoreNet.writeSubDmxStartAddr(subIndex, channelNum, startAddr, dmx_w_type, usePin4, config, current, PortMask);
		}

		// 其他 - DMX 写址事件
		private void dmxAddrOperDoneEventHandler(object source, EventArgs args)
		{
			DmxAddrOperEventArgs dArgs = args as DmxAddrOperEventArgs;

			if (dArgs != null)
			{
				this.BeginInvoke(dmxAddrOperPostHandleDelegate, dArgs);
			}
		}

		// 其他 - DMX 写址事件 - UI界面处理
		private void dmxAddrOperPostHandle(DmxAddrOperEventArgs args)
		{
			if (args.oper.ToLower().Equals("saveaddr"))
			{
				if (args.success)
				{
					string msg = "DMX地址写入成功";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.42");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				}
				else
				{
					string msg = "DMX地址写入失败";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.43");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
			if (args.oper.ToLower().Equals("clearaddr"))
			{
				if (args.success)
				{
					string msg = "DMX地址重置成功";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.44");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				}
				else
				{
					string msg = "DMX地址重置失败";
					if (LanguageOper.available == true)
					{
						msg = LanguageOper.ReadValue(section, "msgStr.45");
					}
					MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
			dmxGroupBox.Enabled = true;
		}

		// 其他 - 高级写址
		private void writeAddrProButton_Click(object sender, EventArgs e)
		{
			bool usePin4 = usePin4CheckBox.Checked;
			
			int dmx_w_type;
			switch (dmxTypeComboBox.SelectedIndex)
			{
				case 2:
					dmx_w_type = 0;
					break;
				case 3:
					dmx_w_type = 1;
					break;
				case 4:
					dmx_w_type = 2;
                    int effecttype = EffectTypeComboList.SelectedIndex << 1 | cmbFirstChan.SelectedIndex;
                    dmx_w_type |= (effecttype & 0xff) << 8;
					break;
				case 5:
					dmx_w_type = 0;
					break;
				default:
					dmx_w_type = 0;
					break;
			}

			// 硬件配置操作前处理
			baseCoreNet.configPreTreat();

			Form_WriteAddrPro writeAddrProForm = new Form_WriteAddrPro(dmx_w_type, usePin4, this);
			writeAddrProForm.setBaseCoreNet(baseCoreNet);
			this.addForm("Form_WriteAddrPro", writeAddrProForm);
			writeAddrProForm.setLanguageText();
			writeAddrProForm.ShowDialog();
			this.removeForm("Form_WriteAddrPro");

			// 硬件配置操作后处理
			baseCoreNet.configPostTreat();
		}

		// 其他 - 分控升级
		private void subUpdateButton_Click(object sender, EventArgs e) 
        {
            try
            {
                if (showPassword()) {// 硬件配置操作前处理
                    baseCoreNet.configPreTreat();
                    Form_SubUpdate subUpdateUI = new Form_SubUpdate(baseCoreNet, baseCoreNet.getActiveDevIndex(), developerEnable);
                    this.addForm("Form_SubUpdate", subUpdateUI);
                    subUpdateUI.setLanguageText();
                    subUpdateUI.ShowDialog(this);
                    this.removeForm("Form_SubUpdate");

                    // 硬件配置操作后处理
                    baseCoreNet.configPostTreat();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + ex.StackTrace);
            }
		}

		// 其他 - 读写 bin
		private void readWriteBinButton_Click(object sender, EventArgs e)
		{
            if (showPassword()) {
                // 硬件配置操作前处理
                baseCoreNet.configPreTreat();

                Form_PlatformTool platformToolUI = new Form_PlatformTool(baseCoreNet, baseCoreNet.getActiveDevIndex());
                this.addForm("Form_PlatformTool", platformToolUI);
                platformToolUI.setLanguageText();
                platformToolUI.ShowDialog(this);
                this.removeForm("Form_PlatformTool");

                // 硬件配置操作后处理
                baseCoreNet.configPostTreat();
            }
		}

		// 其他 - 发送到固定网段（192.168.100.*）
		private void useSocketCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			if (firstShow == false && baseCoreNet != null)
			{
                if (baseCoreNet.setSendDataUseSocket(useSocketCheckBox.Checked))
                {
                    setConfigValue(agentIni, "sendBySocket", useSocketCheckBox.Checked.ToString().ToLower());
                }
                else
                {
                    useSocketCheckBox.Checked = !useSocketCheckBox.Checked;
                }
			}
		}

		// 其他 - socket 发包模式变化
		private void socketSyncRadioButton_CheckedChanged(object sender, EventArgs e)
		{
			if (firstShow == false && baseCoreNet != null)
			{
				if (socketSyncRadioButton.Checked == true)
				{
					baseCoreNet.setSocketSendMode(SocketSendMode.Sync);
					setConfigValue(agentIni, "socketSendMode", "sync");
				}
				else
				{
					baseCoreNet.setSocketSendMode(SocketSendMode.Asyn);
					setConfigValue(agentIni, "socketSendMode", "asyn");
				}
			}
		}

        // 其他 - 网络速度配置变化
        private void radioGigaByte_CheckedChanged(object sender, EventArgs e)
        {

        }
		
		#endregion

		#region Tab 测试 - 业务逻辑

		// 测试 - 查询底层设备链信息（Json格式）
		private void getChainJsonButton_Click(object sender, EventArgs e)
		{
			if (baseCoreNet != null)
			{
				// 获取声明的设备链信息
				List<DMainControl> declareMainControlList = baseCoreNet.getDeclareMainControlList();
				DMainControl dMainControl = new DMainControl();
				if (declareMainControlList != null && declareMainControlList.Count > 0)
				{
					// 目前只支持单主控
					dMainControl = declareMainControlList[0];
				}

				// 拉取检测结果
				List<ControlNode> controlNodeList = baseCoreNet.getControlNodeList();

				List<MacTable> subMacTable = null;
				List<string> macList = null;
				bool useSwitch = baseCoreNet.getUseSwitch();

				// 启用交换机
				if (useSwitch == true)
				{
					subMacTable = baseCoreNet.getLineMacTable("sub");
					macList = baseCoreNet.getMacList();
				}

				if (controlNodeList.Count > 0)
				{
					// 构造 Json 序列化使用的数据结构

					// 主控
					MainControl mainControl = new MainControl(0);
					mainControl.index = 0;

					/****************** 网口主控, 隐藏主控端口和分控链路级 ********************/

					// 主控端口
					MainPort mainPort = new MainPort();
					mainPort.index = 0;
					mainPort.DeclareSubControlNum = dMainControl.declareSubNum;

					// 分控链路
					if (useSwitch == true)
					{
						int subControlChainIndex = 0;
						foreach (string switchPortMac in macList)
						{
							SubControlChain subControlChain = new SubControlChain();
							subControlChain.index = subControlChainIndex;
							//subControlChain.DeclareSubControlNum = dMainControl.declareSubNum;
							mainPort.SubControlChainList.Add(subControlChain);
							subControlChainIndex++;
						}
					}
					else
					{
						SubControlChain subControlChain = new SubControlChain();
						subControlChain.index = 0;
						//subControlChain.DeclareSubControlNum = dMainControl.declareSubNum;
						mainPort.SubControlChainList.Add(subControlChain);
					}

					/****************** 网口主控, 隐藏主控端口和分控链路级 ********************/

					int subControlNum = 0;
					foreach (ControlNode controlNode in controlNodeList)
					{
						if (controlNode.type == 1)
						{
							// 分控 + 分控端口 + 灯具点
							SubControl subControl = new SubControl(controlNode.replyData);
							subControl.index = subControlNum;
							subControl.ProductionInfo.Version = controlNode.version;
							IntPair pair = getDeclarePortAndLampNum(dMainControl, subControl.index);
							if (pair != null)
							{
								subControl.DeclareSubPortNum = pair.val1;
								subControl.DeclareLampNum = pair.val2;
							}

							if (useSwitch == true)
							{
								int macIndex = int.Parse(subMacTable[subControl.index].macIndex);
								mainPort.SubControlChainList[macIndex].SubControlList.Add(subControl);
							}
							else
							{
								mainPort.SubControlChainList[0].SubControlList.Add(subControl);
							}

							subControlNum++;
						}
					}

					if (subControlNum > 0)
					{
						for (int k = 0; k < mainPort.SubControlChainList.Count; k++)
						{
							mainPort.SubControlChainList[k].calcSubChainTotalInfo();
						}

						mainPort.calcMainPortTotalInfo();
						mainControl.MainPortList.Add(mainPort);
						mainControl.calcMainPortTotalInfo();
					}

					if (mainControl == null)
					{
						MessageBoxEx.Show(this, "mainControl is null", tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					}
					else
					{
						string jsonStr = JsonConvert.SerializeObject(mainControl);
						StreamWriter writer = new StreamWriter("chainJson.json");
						writer.WriteLine(jsonStr);
						writer.Flush();
						writer.Close();
						MessageBoxEx.Show(this, jsonStr, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					}
				}
			}
		}

        // 测试 - UID写入
        private void UIDSetButton_Click(object sender, EventArgs e)
        {
            Form_LampUID uidForm = new Form_LampUID(baseCoreNet);
            this.addForm("Form_LampUID", uidForm);
            uidForm.setLanguageText();
            uidForm.ShowDialog();
            this.removeForm("Form_DmxConfig");
        }

		// 测试 - 根据 subIndex 查询声明的分控端口数和灯具数
		private IntPair getDeclarePortAndLampNum(DMainControl dMainControl, int subIndex)
		{
			if (dMainControl == null || dMainControl.declareSubControlList == null)
			{
				return null;
			}

			if (dMainControl.declareSubControlList.Count == 0)
			{
				return null;
			}

			foreach (DSubControl subControl in dMainControl.declareSubControlList)
			{
				if (subControl.subControlIndex == subIndex)
				{
					return new IntPair(subControl.declarePortNum, subControl.declareLampNum);
				}
			}

			return null;
		}

		// 测试 - 分控测试
		private void testSubControlButton_Click(object sender, EventArgs e)
		{
			if (baseCoreNet != null)
			{
				DispConfigPacketPara dispPara = baseCoreNet.getDispConfigPacketPara();
				dispPara.testMode = 0x3C;
				baseCoreNet.setDispConfigPacketPara(dispPara);
				string msg = "测试模式";
				if (LanguageOper.available == true)
				{
					msg = LanguageOper.ReadValue(section, "msgStr.47");
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				dispPara.testMode = 0x00;
				baseCoreNet.setDispConfigPacketPara(dispPara);
			}
		}

		// 测试 - 周期下发 Sub - 选择 - 显示菜单
		private void selectSub4SendButton_Click(object sender, EventArgs e)
		{
			// 设置 menu 显示位置
			this.contextMenuStrip_Sub2 = new System.Windows.Forms.ContextMenuStrip();
			string fontName = this.Font.Name;
			contextMenuStrip_Sub2.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
			AddContextMenu("打开", contextMenuStrip_Sub2.Items, selectSub4Send_Open);
			AddContextMenu("默认", contextMenuStrip_Sub2.Items, selectSub4Send_Default);
			if (LanguageOper.available == true)
			{
				contextMenuStrip_Sub2.Items[0].Text = LanguageOper.ReadValue(section, "contextMenuStrip_Sub2.ItemsText.0");
				contextMenuStrip_Sub2.Items[1].Text = LanguageOper.ReadValue(section, "contextMenuStrip_Sub2.ItemsText.1");
			}
			Point pt = new Point(selectSub4SendButton.Location.X, selectSub4SendButton.Location.Y + selectSub4SendButton.Height);
			this.contextMenuStrip_Sub2.Show(this.autoSendSubGroupBox, pt);
			this.BringToFront();
		}

		// 测试 - 周期下发 Sub - 选择 - 打开
		private void selectSub4Send_Open(object sender, EventArgs e)
		{
			OpenFileDialog o = new OpenFileDialog();
			o.Filter = "Sub Files(*.sub)|*.sub";
			o.Multiselect = false;
			if (Directory.Exists(lastPath_SubFileSend))
			{
				o.InitialDirectory = lastPath_SubFileSend;
			}
			else
			{
				o.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
			}
			DialogResult dr = o.ShowDialog();
			if (dr == DialogResult.OK)
			{
				lastPath_SubFileSend = (new FileInfo(o.FileName)).DirectoryName;

				sub4SendTextBox.Text = o.FileName;
				sub4SendTextBox.SelectionStart = sub4SendTextBox.Text.Length;
				sub4SendTextBox.ScrollToCaret();

				// 更新 Agent.ini - 停用
				//setConfigValue(agentIni, "subDataName", sub4SendTextBox.Text.Trim());

				if (autoSendSubEnable == true)
				{
					baseCoreNet.setSubConfigPacketData(sub4SendTextBox.Text.Trim());
				}
			}
		}

		// 测试 - 周期下发 Sub - 选择 - 默认
		private void selectSub4Send_Default(object sender, EventArgs e)
		{
			string defaultSubFilePath = ZqConfig.GetAppPath() + @"\conf\config_rgb.sub";
			if (File.Exists(defaultSubFilePath))
			{
				sub4SendTextBox.Text = "config_rgb.sub";

				// 更新 Agent.ini - 停用
				//setConfigValue(agentIni, "subDataName", "config_rgb.sub");

				if (autoSendSubEnable == true)
				{
					baseCoreNet.setSubConfigPacketData(defaultSubFilePath);
				}
			}
			else
			{
				string msg = string.Format("找不到默认的 sub 文件 {0}", defaultSubFilePath);
				if (LanguageOper.available == true)
				{
					msg = string.Format(LanguageOper.ReadValue(section, "msgStr.49"), defaultSubFilePath);
				}
				MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		// 测试 - 周期下发 Sub - 开始/停止
		private void sendSubButton_Click(object sender, EventArgs e)
		{
			if (autoSendSubEnable == false)
			{
				if (!sub4SendTextBox.Text.Trim().Equals(""))
				{
					string tmpFileName = sub4SendTextBox.Text.Trim();

					if (!File.Exists(tmpFileName) && File.Exists(ZqConfig.GetAppPath() + @"\conf\" + tmpFileName))
					{
						tmpFileName = ZqConfig.GetAppPath() + @"\conf\" + tmpFileName;
					}
					else if (!File.Exists(tmpFileName))
					{
						string msg = string.Format("无法找到文件 {0}，是否下发默认文件 config_rgb.sub？", tmpFileName);
						if (LanguageOper.available == true)
						{
							msg = string.Format(LanguageOper.ReadValue(section, "msgStr.50"), tmpFileName);
						}
						DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
						if (dr == DialogResult.Yes)
						{
							if (File.Exists(ZqConfig.GetAppPath() + @"\conf\config_rgb.sub"))
							{
								sub4SendTextBox.Text = "config_rgb.sub";
								tmpFileName = ZqConfig.GetAppPath() + @"\conf\config_rgb.sub";
							}
							else
							{
								string msg1 = "无法找到默认文件 config_rgb.sub";
								if (LanguageOper.available == true)
								{
									msg1 = LanguageOper.ReadValue(section, "msgStr.51");
								}
								MessageBoxEx.Show(this, msg1, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
								return;
							}
						}
						else
						{
							return;
						}
					}

					// 更新 Agent.ini - 停用
					//setConfigValue(agentIni, "subDataName", sub4SendTextBox.Text.Trim());
					//setConfigValue(agentIni, "sendSubEnable", "true");

					// 触发底层操作
					baseCoreNet.setSubConfigPacketData(tmpFileName);
					baseCoreNet.setSubConfigSendEnable(true);

					sendSubButton.Text = "停止下发";
					if (LanguageOper.available == true)
					{
						sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Stop");
					}
					autoSendSubEnable = true;
				}
			}
			else
			{
				// 更新 Agent.ini - 停用
				//setConfigValue(agentIni, "sendSubEnable", "false");
				
				baseCoreNet.setSubConfigSendEnable(false);
				
				sendSubButton.Text = "开始下发";
				if (LanguageOper.available == true)
				{
					sendSubButton.Text = LanguageOper.ReadValue(section, "sendSubButton.Text.Start");
				}
				autoSendSubEnable = false;
			}
		}

		// 测试 - 通信包计数复位
		private void resetPacketNumButton_Click(object sender, EventArgs e)
		{
			baseCoreNet.sendClearPacketCommand(baseCoreNet.getActiveDevIndex());
		}

		// 测试 - RDM 协议测试
		private void rdmTestButton_Click(object sender, EventArgs e)
		{
			Form_DetectRDM_Test rdmTestForm = new Form_DetectRDM_Test();
			this.addForm("Form_DetectRDM_Test", rdmTestForm);
			rdmTestForm.setLanguageText();
			rdmTestForm.setBaseCoreNet(baseCoreNet);
			rdmTestForm.ShowDialog();
			this.removeForm("Form_DetectRDM_Test");
		}

		// 测试 - DMX 灯具配置
		private void dmxConfigButton_Click(object sender, EventArgs e)
		{
			Form_DmxConfig dmxConfigForm = new Form_DmxConfig(baseCoreNet, this);
			this.addForm("Form_DmxConfig", dmxConfigForm);
			dmxConfigForm.setLanguageText();
			dmxConfigForm.ShowDialog();
			this.removeForm("Form_DmxConfig");
		}

		// 测试 - 灯具 MCU 升级
		private void lampMcuUpdateButton_Click(object sender, EventArgs e)
		{
			Form_ReceiverControl receiverControlForm = new Form_ReceiverControl(this, baseCoreNet);
			this.addForm("Form_ReceiverControl", receiverControlForm);
			receiverControlForm.setLanguageText();
			receiverControlForm.ShowDialog();
			this.removeForm("Form_ReceiverControl");
		}

        // 测试 - 放大器 MCU 升级
        private void AmpMcuUpdateButton_Click(object sender, EventArgs e)
        {
            Form_AmpControl ampControlForm = new Form_AmpControl(this, baseCoreNet);
            this.addForm("Form_AmpControl", ampControlForm);
            ampControlForm.setLanguageText();
            ampControlForm.ShowDialog();
            this.removeForm("Form_AmpControl");
        }

		// 测试 - 控制器 MCU 升级 - 集成外部程序
		private void controlMcuUpdateButton_Click(object sender, EventArgs e)
		{
			Thread t = new Thread(() =>
			{
				var fi = new FileInfo(Application.StartupPath + "/YS1028Tool/YS1028Tool.exe");
				if (!fi.Exists)
				{
					string msg = string.Format("文件 {0} 不存在", fi.FullName);
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.18"), fi.FullName);
					}
					MessageBox.Show(msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
					return;
				}
				var processes = Process.GetProcessesByName("YS1028Tool");
				if (processes.Any())
				{
					var processStarted = processes.First();
					SetForegroundWindow(processStarted.MainWindowHandle);
					return;
				}

				ProcessStartInfo pst = new ProcessStartInfo();
				pst.WorkingDirectory = fi.DirectoryName;
				pst.FileName = fi.FullName;
				try
				{
					Process.Start(pst);
				}
				catch (Exception)
				{
					string msg = string.Format("外部进程 {0} 启动失败", fi.FullName);
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.48"), fi.FullName);
					}
					MessageBox.Show(msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
				}
			});
			t.IsBackground = true;
			t.Start();
		}

		// 测试 - 网格屏配置
		private void gridConfigButton_Click(object sender, EventArgs e)
		{
			Form_GridConfig gridConfigForm = new Form_GridConfig(this, baseCoreNet);
			this.addForm("Form_GridConfig", gridConfigForm);
			gridConfigForm.setLanguageText();
			gridConfigForm.ShowDialog();
			this.removeForm("Form_GridConfig");
		}

        //// 测试 - ArtNet测试
        //private void ArtNetTestButton_Click(object sender, EventArgs e)
        //{
        //    Thread t = new Thread(() =>
        //    {
        //        var fi = new FileInfo(Application.StartupPath + "/ArtNetTest/ArtSubControllerSimulator.exe");
        //        if (!fi.Exists)
        //        {
        //            string msg = string.Format("文件 {0} 不存在", fi.FullName);
        //            if (LanguageOper.available == true)
        //            {
        //                msg = string.Format(LanguageOper.ReadValue(section, "msgStr.18"), fi.FullName);
        //            }
        //            MessageBox.Show(msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
        //            return;
        //        }
        //        var processes = Process.GetProcessesByName("ArtNetTest");
        //        if (processes.Any())
        //        {
        //            var processStarted = processes.First();
        //            SetForegroundWindow(processStarted.MainWindowHandle);
        //            return;
        //        }

        //        ProcessStartInfo pst = new ProcessStartInfo();
        //        pst.WorkingDirectory = fi.DirectoryName;
        //        pst.FileName = fi.FullName;
        //        try
        //        {
        //            Process.Start(pst);
        //        }
        //        catch (Exception)
        //        {
        //            string msg = string.Format("外部进程 {0} 启动失败", fi.FullName);
        //            if (LanguageOper.available == true)
        //            {
        //                msg = string.Format(LanguageOper.ReadValue(section, "msgStr.48"), fi.FullName);
        //            }
        //            MessageBox.Show(msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
        //        }
        //    });
        //    t.IsBackground = true;
        //    t.Start();
        //}

		// 测试 - 主控连接状态模拟
		private void mainControlConnectedComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			mainControlConnected = mainControlConnectedComboBox.SelectedIndex;
		}

		// 测试 - 主控 DVI 状态模拟
		private void mainControlStatusComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			mainControlDviMode = mainControlStatusComboBox.SelectedIndex;
		}

		// 测试 - 返回主控 DVI 状态模拟值
		public int getMainControlDviMode()
		{
			return mainControlDviMode;
		}

		// 测试 - 返回主控连接状态模拟值
		public int getMainControlConnected()
		{
			return mainControlConnected;
		}

		// 测试 - 设置软件语言
		private void languageComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (languageChangeEnable == false)
			{
				return;
			}

			if (languageComboBox.SelectedIndex == 0)
			{
				LanguageOper.LocalLanguage = LanguageEnum.CHS;
			}
			else if (languageComboBox.SelectedIndex == 1)
			{
				LanguageOper.LocalLanguage = LanguageEnum.EN;
			}
			if (languageComboBox.SelectedIndex == 2)
			{
				LanguageOper.LocalLanguage = LanguageEnum.CHT;
			}

			// 设置界面文字
			setLanguageText();
		}

		#endregion

		#region 辅助功能 - 配置文件读写、更新后台操作进度、根据索引获取颜色描述

		// 从配置文件 configFilePath 中读取 key 的值 value, 若无此配置或者读取错误, 返回空串 ""
		private string getConfigValue(string configFilePath, string key)
		{
			StreamReader sr = null;
			try
			{
				if (File.Exists(configFilePath))
				{
					sr = new StreamReader(new FileStream(configFilePath, FileMode.Open));
					string returnValue = "";
					while (true)
					{
						string line = sr.ReadLine();
						if (line == null)
						{
							break;
						}
						else if (line.Trim().ToLower().StartsWith(key.ToLower()))
						{
							string[] subStr = line.Split('=');
							if (subStr.Length >= 2)
							{
								returnValue = subStr[1];
							}
						}
					}
					return returnValue;
				}
				else
				{
					return "";
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + ex.StackTrace);
				return "";
			}
			finally
			{
				if (sr != null)
				{
					sr.Close();
				}
			}
		}

		// 向配置文件 configFilePath 中写入 key 的值 value, 若成功返回true, 失败返回false
		private bool setConfigValue(string configFilePath, string key, string value)
		{
			StreamReader sr = null;
			StreamWriter sw = null;
			try
			{
				if (File.Exists(configFilePath))
				{
					sr = new StreamReader(new FileStream(configFilePath, FileMode.Open));
					sw = new StreamWriter(new FileStream(configFilePath + ".tmp", FileMode.Create));
					while (true)
					{
						string line = sr.ReadLine();
						if (line == null)
						{
							break;
						}
						else if (line.Trim().ToLower().StartsWith(key.ToLower()))
						{
							string[] subStr = line.Split('=');
							line = subStr[0] + "=" + value;
							sw.WriteLine(line);
						}
						else
						{
							sw.WriteLine(line);
						}
					}
					sr.Close();
					sw.Flush();
					sw.Close();
					sw = null;

					try
					{
						File.Delete(configFilePath);
						File.Move(configFilePath + ".tmp", configFilePath);
					}
					catch (Exception)
					{
						;
					}

					return true;
				}
				else
				{
					return false;
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + ex.StackTrace);
				return false;
			}
		}

		// 更新后台操作进度
		public void updateApplyOrTestSubSendProcess(object sender, EventArgs e)
		{
			WriteEventArgs eArgs = e as WriteEventArgs;
			if (eArgs != null)
			{
				this.BeginInvoke(updateOperationProgressDelegate, eArgs);
			}
		}

		// 更新后台操作进度 - 实际方法
		private void updateOperationProgress(WriteEventArgs eArgs)
		{
			int value = eArgs.processValue;
			string operation = eArgs.operation;
			string errorMsg = eArgs.errorMsg;

            if (!this.Visible)
            { 
                return;
            }

			#region 当前操作 - 下载sub文件
			
			if (operation.Equals("DownloadSub"))
			{
				// 下载布线操作被强制停止
				if (eArgs.total == -1)
				{
					MessageBoxEx.Show(this, String.Format("强制停止成功，当前已下载完成 {0} 个分控。", eArgs.current), "提示", MessageBoxButtons.OK, MessageBoxIcon.None);

					// 重置下载 sub 相关按钮为初始状态
					resetApplySubButtonAndProcess();

					return;
				}
				// 线程中出现错误, 恢复按钮
				if (value == -1)
				{
					MessageBoxEx.Show(this, "下载sub文件：后台操作存在错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.None);

					// 重置下载 sub 相关按钮为初始状态
					resetApplySubButtonAndProcess();
				}

				if (subSendApplyOrTest.Equals("apply") && value >= 0 && value <= 100)
				{
					applySendProgressBar.Value = value;
					if (l9ProSetDlg.Visible == true)
					{
						l9ProSetDlg.BeginInvoke(l9ProSetDlg.setApplySendProgressDelegate, value);
					}
				}
				else if (subSendApplyOrTest.Equals("test") && value >= 0 && value <= 100)
				{
					applySendProgressBar.Value = value;
					if (l9ProSetDlg.Visible == true)
					{
						l9ProSetDlg.BeginInvoke(l9ProSetDlg.setTestSendProgressDelegate, value);
					}
				}

				if (value == 100)
				{
					MessageBoxEx.Show(this, "sub 文件下发完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.None);

					applySubButton.Enabled = true;
					//forceStopApplySubButton.Enabled = false;
					testSubButton.Enabled = true;
					//resetSubButton.Enabled = true;
					checkSubButton.Enabled = true;

					if (l9ProSetDlg.Visible == true)
					{
						l9ProSetDlg.BeginInvoke(l9ProSetDlg.setSubSendButtonEnableDelegate, true);
					}

					if (subSendApplyOrTest.Equals("apply"))
					{
						applySendProgressBar.Value = 0;
						if (l9ProSetDlg.Visible == true)
						{
							l9ProSetDlg.BeginInvoke(l9ProSetDlg.setApplySendProgressDelegate, 0);
						}
					}
					else if (subSendApplyOrTest.Equals("test"))
					{
						applySendProgressBar.Value = 0;
						if (l9ProSetDlg.Visible == true)
						{
							l9ProSetDlg.BeginInvoke(l9ProSetDlg.setTestSendProgressDelegate, 0);
						}
					}

					subDataIsDownloading = false;
				}

				return;
			}
			
			#endregion
		}

		// 重置下载 sub 相关按钮为初始状态
		private void resetApplySubButtonAndProcess()
		{
			applySubButton.Enabled = true;
			//forceStopApplySubButton.Enabled = false;
			testSubButton.Enabled = true;
			//resetSubButton.Enabled = true;
			
			if (subSendApplyOrTest.Equals("apply"))
			{
				applySendProgressBar.Value = 0;
				if (l9ProSetDlg.Visible == true)
				{
					l9ProSetDlg.BeginInvoke(l9ProSetDlg.setApplySendProgressDelegate, 0);
				}
			}
			else if (subSendApplyOrTest.Equals("test"))
			{
				applySendProgressBar.Value = 0;
				if (l9ProSetDlg.Visible == true)
				{
					l9ProSetDlg.BeginInvoke(l9ProSetDlg.setTestSendProgressDelegate, 0);
				}
			}

			subDataIsDownloading = false;
		}

		// 辅助函数：根据索引获取颜色描述
		private char getColorChar(byte colorIndex)
		{
			switch (colorIndex)
			{
				case 0:
					return 'R';
				case 1:
					return 'G';
				case 2:
					return 'B';
				case 3:
					return 'N';
				case 4:
					return 'W';
				case 5:
					return 'Y';
				default:
					return 'N';
			}
		}

		// 更新后台操作进度 - 清除分控序号
		private void updateClearSubPositonProgress(int currentNum, int totalNum)
		{
			if (totalNum == 0)
			{
				return;
			}

			int value = currentNum * 100 / totalNum;
			if (value < 0 || value > 100)
			{
				return;
			}

			if (value == 0)
			{
                //fixSubPositionCheckBox.Enabled = false;
                //fixSubPositionButton.Enabled = false;
                //clearSubPositionButton.Enabled = false;
			}
			else if (value == 100)
			{
                //fixSubPositionCheckBox.Enabled = true;
                //fixSubPositionButton.Enabled = fixSubPositionCheckBox.Checked;
                //clearSubPositionButton.Enabled = fixSubPositionCheckBox.Checked;
                var msg = "分控序号清除完成";
                if (LanguageOper.available)
                {
                    msg = LanguageOper.ReadValue(section, "msgStr.52");
                }
                Tools.ShowTipMessage(this, msg);
			}
		}

		// 显示提示信息
		private void showTipMessage(string msg, string head, MessageBoxButtons button, MessageBoxIcon icon)
		{
			MessageBoxEx.Show(this, msg, head, button, icon);
		}

		#endregion

        #region 用户颜色设置
        // 用户颜色设置 - 颜色变化响应
        private void userColorChanged(int userColorType)
        {
            if (this.InvokeRequired)
            { 
                this.Invoke(new MethodInvoker(delegate()
                {
                    this.userColorChanged(userColorType);
                }));
            }
            else
            {
                setUserColor(userColorType);
                if (this.baseCoreNet.getSubControlNum() > 0)
                {
                    userColorTestSub();
                }
            }
        }

        // 用户颜色设置 - 设置颜色
        private void setUserColor(int userColorType)
        {
            this.userColorType = userColorType;
            if ((userColorType >= 0) && (userColorType != 255))
            {
                rvCardL9Config.fourColorMode = userColorType;
                StringBuilder sb = new StringBuilder();
                byte[] manualColorArrayPara = rvCardL9Config.GetManualColorArray();
                switch (userColorType)
                {
                    case 0:
                        // 三色模式
                        baseCoreNet.setBaseMapMode(MapMode.Baned);
                        for (int i = 1; i < 8; i += 2)
                        {
                            if (manualColorArrayPara[i] == 4) manualColorArrayPara[i] = 3;
                        }
                        break;
                    case 1:
                        // 四色纯模式
                        baseCoreNet.setBaseMapMode(MapMode.FourPure);
                        for (int i = 1; i < 8; i += 2)
                        {
                            if (manualColorArrayPara[i] == 3) manualColorArrayPara[i] = 4;
                        }
                        break;
                    case 2:
                        // 四色增强模式
                        baseCoreNet.setBaseMapMode(MapMode.FourIncrease);
                        for (int i = 1; i < 8; i += 2)
                        {
                            if (manualColorArrayPara[i] == 3) manualColorArrayPara[i] = 4;
                        }
                        break;
                }
                sb.Append(getColorChar(manualColorArrayPara[1]));
                sb.Append(getColorChar(manualColorArrayPara[3]));
                sb.Append(getColorChar(manualColorArrayPara[5]));
                sb.Append(getColorChar(manualColorArrayPara[7]));
                baseCoreNet.setBaseColorString(sb.ToString());

                rvCardL9Config.SetManualColorArray(manualColorArrayPara);
            }
            else if (userColorType == 255)
            {
                rvCardL9Config.fourColorMode = defaultColorType;
                StringBuilder sb = new StringBuilder();
                byte[] manualColorArrayPara = rvCardL9Config.GetManualColorArray();
                switch (defaultColorType)
                {
                    case 0:
                        // 三色模式
                        baseCoreNet.setBaseMapMode(MapMode.Baned);
                        for (int i = 1; i < 8; i += 2)
                        {
                            if (manualColorArrayPara[i] == 4) manualColorArrayPara[i] = 3;
                        }
                        break;
                    case 1:
                        // 四色纯模式
                        baseCoreNet.setBaseMapMode(MapMode.FourPure);
                        for (int i = 1; i < 8; i += 2)
                        {
                            if (manualColorArrayPara[i] == 3) manualColorArrayPara[i] = 4;
                        }
                        break;
                    case 2:
                        // 四色增强模式
                        baseCoreNet.setBaseMapMode(MapMode.FourIncrease);
                        for (int i = 1; i < 8; i += 2)
                        {
                            if (manualColorArrayPara[i] == 3) manualColorArrayPara[i] = 4;
                        }
                        break;
                }
                sb.Append(getColorChar(manualColorArrayPara[1]));
                sb.Append(getColorChar(manualColorArrayPara[3]));
                sb.Append(getColorChar(manualColorArrayPara[5]));
                sb.Append(getColorChar(manualColorArrayPara[7]));
                baseCoreNet.setBaseColorString(sb.ToString());

                rvCardL9Config.SetManualColorArray(manualColorArrayPara);
            }

            updateMapModeAndColorString();
            saveCurrentChipConfig();
        }
        // 用户颜色设置 - 下发测试sub
        private void userColorTestSub()
        {
            List<ControlNode> controlNodeList = baseCoreNet.getControlNodeList();
            int totalSubCtrlNum = controlNodeList == null ? 0 : controlNodeList.Count;
            if (totalSubCtrlNum == 0)
            {
                string msg = "当前未检测到分控";
                if (LanguageOper.available == true)
                {
                    msg = LanguageOper.ReadValue(section, "msgStr.2");
                }
                MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            SelectedSubInfo selectedSubInfo = new SelectedSubInfo();
            selectedSubInfo.overall = true;
            foreach (ControlNode node in controlNodeList)
            {
                if (node.type == 1)
                {
                    selectedSubInfo.targetSubIndexList.Add(node.mySubCtrlDepth + 1);
                }
            }
            bool res = testSub(selectedSubInfo);
            
        }
        #endregion

        #region 多语言国际化

        public void addForm(string key, Form valueForm)
		{
			if (formDictionary.ContainsKey(key))
			{
				formDictionary.Remove(key);
			}

			formDictionary.Add(key, valueForm);
		}

		public void removeForm(string key)
		{
			formDictionary.Remove(key);
		}

		public void setSubFormText()
		{
			foreach (string key in formDictionary.Keys)
			{
				try
				{
					switch (key)
					{
						case "Form_CheckSubData":
							{
								((Form_CheckSubData)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_ChipSet":
							{
								((Form_ChipSet)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_DetectDetail":
							{
								((Form_DetectDetail)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_DetectRDM_Test":
							{
								((Form_DetectRDM_Test)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_DmxConfig":
							{
								((Form_DmxConfig)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_DmxCurrentPro":
							{
								((Form_DmxCurrentPro)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_DownloadLwf":
							{
								((Form_DownloadLwf)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_EditSwitchConfig":
							{
								((Form_EditSwitchConfig)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_FixSubPos":
							{
								((Form_FixSubPos)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_GridConfig":
							{
								((Form_GridConfig)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_NewOrSelect":
							{
								((Form_NewOrSelect)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_Password":
							{
								((Form_Password)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_PlatformTool":
							{
								((Form_PlatformTool)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_ProSet":
							{
								((Form_ProSet)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_ReceiverControl":
							{
								((Form_ReceiverControl)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_SelectSub":
							{
								((Form_SelectSub)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_SelectSubEx":
							{
								((Form_SelectSubEx)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_StartAddrMap":
							{
								((Form_StartAddrMap)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_SubDetail":
							{
								((Form_SubDetail)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_SubUpdate":
							{
								((Form_SubUpdate)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_WriteAddrPro":
							{
								((Form_WriteAddrPro)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_DelPortDataMode":
							{
								((Form_DelPortDataMode)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_NewWriteAddrPro":
							{
								((Form_NewWriteAddrPro)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_QuickEditAddr":
							{
								((Form_QuickEditAddr)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_SelectRange":
							{
								((Form_SelectRange)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_SubParaWriteAddrPro":
							{
								((Form_SubParaWriteAddrPro)(formDictionary[key])).setLanguageText();
								break;
							}
						case "Form_FullPower":
							{
								((Form_FullPower)(formDictionary[key])).setLanguageText();
								break;
							}
						default:
							break;
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
				}
			}
		}

		#endregion

        public int getSubControllerNum()
        {
            return baseCoreNet.getSubControlNum();
        }

        private void chbShowMainControl_CheckedChanged(object sender, EventArgs e)
        {
            // TODO : 控制输出使能
        }

        private void onUpdateStatusStr(string msg)
        {
            //lblStatus.Text = string.Format("Status = {0}", msg);
        }

        private void forceStopApplySubButton_Click(object sender, LayoutEventArgs e) {

        }

        private void rbFormLwf_CheckedChanged(object sender, EventArgs e) {
            var addrMapEnable = rbFromLwf.Checked;
            pnlChannelSet.Enabled = !addrMapEnable;
            //baseCoreNet.setAddrMapEnable(addrMapEnable);
        }

        private void rbManual_CheckedChanged(object sender, EventArgs e) {
            //pnlChannelSet.Enabled = true;
        }

        private void btnLwfFileInfo_Click(object sender, EventArgs e) {
            frmLwfPara.setLanguageText();
            frmLwfPara.ShowDialog();
        }

        private void rbFormLwf2_CheckedChanged(object sender, EventArgs e) {
            pnlChannelSet2.Enabled = false;
        }

        private void rbManual2_CheckedChanged(object sender, EventArgs e) {
            pnlChannelSet2.Enabled = true;
        }

        private void colorOrderComboBox2_SelectedIndexChanged(object sender, EventArgs e) {
            
        }

        private void custRadioButton2_CheckedChanged(object sender, EventArgs e) {
            
        }

        private void manualRadioButton2_CheckedChanged(object sender, EventArgs e) {
            
        }

        private void btnLampSet_Click(object sender, EventArgs e) {
            var form = new Form_LampSet(baseCoreNet);
            form.ShowDialog(this);
        }

        private void btnApplyNetSet_Click(object sender, EventArgs e) {
            var selSubInfo = new SelectedSubInfo();
            var form = new Form_SelectSub(selSubInfo, baseCoreNet);
            form.StartPosition = FormStartPosition.CenterParent;
            if (form.ShowDialog() == DialogResult.OK) {
                var speed = NetSpeed.GigaByte;
                if (radioHundredMegaByte.Checked) {
                    speed = NetSpeed.HundredMegaByte;
                }

                baseCoreNet.SetNetSpeed(speed);
                setConfigValue(agentIni, "netSpeed", speed == NetSpeed.GigaByte ? "giga" : "mega");
                if (form.selectMode == 0) {
                    baseCoreNet.setSubMegaByteMode(-1, speed);
                } else if (form.selectMode == 1) {
                    var start = form.startSub;
                    var end = form.endSub;
                    for (var i = start; i <= end; i++) {
                        baseCoreNet.setSubMegaByteMode(i, speed);
                    }
                }
                
                
            }
        }

        private void btnSubIndex_Click(object sender, EventArgs e) {
            var form = new Form_SubIndex(this);
            form.ShowDialog();
        }

        private void cmbChipType_DropDown(object sender, EventArgs e) {
            loadChip();
        }

        // 参数配置
        private void btnChipConfig_Click(object sender, EventArgs e) {
            var chip = dmxTypeComboBox.Text;
            switch (chip) {
                case "UCS512D":
                    var formUCS512D = new Form_ChipConfigUCS512D(this, baseCoreNet);
                    formUCS512D.ShowDialog();
                    break;
                case "UCS512E":
                    var formUCS512E = new Form_ChipConfigUCS512E(this, baseCoreNet);
                    formUCS512E.ShowDialog();
                    break;
                case "SM17500":
                    var formSM17500 = new Form_ChipConfigSM17500(this, baseCoreNet);
                    formSM17500.ShowDialog();
                    chipCurrentMode = formSM17500.currMode;
                    break;
            }
        }

        // 电流配置
        private void btnChipCurrent_Click(object sender, EventArgs e) {
            var max = 0;
            var curr = max;
            getCurrVal(dmxTypeComboBox.Text, out max, out curr);
            var form = new Form_ChipCurrent(this, baseCoreNet, max, curr);
            form.ShowDialog();
        }

        // 自通道配置
        private void btnSelfChan_Click(object sender, EventArgs e) {
            if (!showPassword()) {
                return;
            }
            var max = 0;
            var curr = max;
            getSelfChanVal(dmxTypeComboBox.Text, out max, out curr);
            var form = new Form_ChipChannel(this, baseCoreNet, max, curr);
            form.ShowDialog();
        }

        private void getCurrVal(string chip,out int max, out int val) {
            max = 255;
            val = max;
            switch (chip) {
                case "UCS512D":
                    max = 63;
                    val = 63;
                    break;
                case "UCS512E":
                    max = 15;
                    val = 15;
                    break;
                case "SM17500":
                    if (chipCurrentMode == 0) {
                        max = 0;
                        val = 0;
                    } else {
                        max = 8 << chipCurrentMode;
                        max--;
                        val = max;
                    }
                    break;
            }
        }

        private void getSelfChanVal(string chip, out int max, out int val) {
            max = 255;
            val = max;
            switch (chip) {
                case "UCS512E":
                    max = 128;
                    val = max;
                    break;
                case "SM17500":
                    max = 255;
                    val = max;
                    break;
            }
        }

        public void SetChipConfig(byte[] config) {
            writeAddrMode = 1;
            chipConfig1 = config;
        }

        public void SetChipCurrent(byte[] current) {
            writeAddrMode = 2;
            chipConfig2 = current;
        }

        public void SetSelfChanVal(byte[] val) {
            writeAddrMode = 3;
            chipConfig2 = val;
        }

        public void DmxSaveButtonClick() {
            dmxSaveButton_Click(null, null);
        }

        private bool showPassword() {
            return showPassword(passwordString);
        }

        private bool showPassword(string pass) {
            Form_Password passwordForm = new Form_Password(pass);
            this.addForm("Form_Password", passwordForm);
            passwordForm.setLanguageText();
            DialogResult dr = passwordForm.ShowDialog();
            this.removeForm("Form_Password");
            if (dr == System.Windows.Forms.DialogResult.Yes) {
                return true;
            } else {
                if (passwordForm.hasInputPassword() == true) {
                    string msg = "密码错误";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "msgStr.46");
                    }
                    MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.None);
                }
                return false;
            }
        }

        private void cmbDetectType_SelectedIndexChanged(object sender, EventArgs e) {
            var selIndex = cmbDetectType.SelectedIndex;
            var autoFlag = false;
            if (selIndex != 1) {
                //cmbDetectMode.Enabled = false;
                btnRequeryUIDList.Visible = false;
                autoFlag = false;
            } else {
                //cmbDetectMode.Enabled = true;
                btnRequeryUIDList.Visible = true;
                autoFlag = true;
            }
            if (!initDone) {
                return;
            }
            lampDetectType = (DetectType)selIndex;
            baseCoreNet.setDetectType(lampDetectType);
        }

        private void cmbDetectMode_SelectedIndexChanged(object sender, EventArgs e) {
            if (!initDone) {
                return;
            }
            if (lampDetectType == DetectType.Normal) {
                return;
            }
            var mode = (LampCheckMode)cmbDetectMode.SelectedIndex;
            if (mode == LampCheckMode.UseLwf) {
                var valid = true;
                if (!baseCoreNet.getAddrMapEnable()) {
                    valid = false;
                } else {
                    if (subTubeDataList == null || subTubeDataList.Count == 0) {
                        valid = false;
                    }
                }
                if (!valid) {
                    string msg = "布线文件中不存在有效灯具点, 将保持当前的检测模式";
                    //if (LanguageOper.available == true) {
                    //    msg = LanguageOper.ReadValue(section, "msgStr.3");
                    //}

                    MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);

                    cmbDetectMode.SelectedIndex = (int)lastLampDetectMode;

                    return;
                }
            } else if (mode == LampCheckMode.UseResult) {
                var valid = true;
                var baseChain = baseCoreNet.GetBaseArtDevChain();
                if (baseChain == null) {
                    valid = false;
                } else if (baseChain.DetailList.Count == 0) {
                    valid = false;
                }
                if (!valid) {
                    string msg = "基准设备链不存在, 将保持当前的检测模式";
                    //if (LanguageOper.available == true) {
                    //    msg = LanguageOper.ReadValue(section, "msgStr.3");
                    //}

                    MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);

                    cmbDetectMode.SelectedIndex = (int)lastLampDetectMode;

                    return;
                }
            }
            lastLampDetectMode = mode;
            refreshMainTree_Total(lastMainControl);
        }

        private void changeDetectMode() {
            if (InvokeRequired) {
                this.Invoke(new Action(() => { changeDetectMode(); }));
            } else {
                cmbDetectMode.SelectedIndex = (int)lampDetectMode;
            }
        }

        private void btnOper_Click(object sender, EventArgs e) {
            var strip_oper = new System.Windows.Forms.ContextMenuStrip();
            string fontName = this.Font.Name;
            strip_oper.Font = new System.Drawing.Font(fontName, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));
            AddContextMenu("展开至分控", strip_oper.Items, expandToSubButton_Click);
            AddContextMenu("分控详情", strip_oper.Items, subDetailButton_Click);
            AddContextMenu("灯具详情", strip_oper.Items, viewDetailButton_Click);
            AddContextMenu("通讯计数包复位", strip_oper.Items, resetPacketNumButton_Click);
            if (lampDetectType == DetectType.ArtNet) {
                AddContextMenu("以当前灯具为基准", strip_oper.Items, btnSetCurrChainToBase_Click);
            }
            //if (LanguageOper.available == true) {
            //    strip_expand.Items[0].Text = LanguageOper.ReadValue(section, "contextAddrMap.ItemsText.0");
            //    strip_expand.Items[1].Text = LanguageOper.ReadValue(section, "contextAddrMap.ItemsText.1");
            //    strip_expand.Items[2].Text = LanguageOper.ReadValue(section, "readLampParaButton.Text.1");
            //}
            Point pt = new Point(btnOper.Location.X, btnOper.Location.Y + btnOper.Height);
            strip_oper.Show(this.infoSplitContainer, pt);
            this.BringToFront();
        }

        private void btnRequeryUIDList_Click(object sender, EventArgs e) {
            if (!initDone) {
                return;
            }
            baseCoreNet.RequeryUIDListTotal_Sub();
        }

        private void btnSetCurrChainToBase_Click(object sender, EventArgs e) {
            if (!initDone) {
                return;
            }
            if (baseCoreNet.GetCurrArtDeviceDetailList() == null) {
                return;
            }
            var artDevChain = baseCoreNet.GetCurrArtDeviceDetailList().Clone();
            baseCoreNet.SetBaseArtDevChain(artDevChain);
            artDevChain.SaveToFile(artDevChainIni);
        }

        public void  setRequeryWaitTime(int waitTime) {
            if (waitTime < 5 || waitTime > 500) {
                var msg = "灯具刷新延时需要在[5,500]秒之间";
                MessageBox.Show(msg);
                return;
            }
            baseCoreNet.SetRequeryWaitTime(waitTime);
            setConfigValue(agentIni, "requeryWaitTime", waitTime.ToString());
        }

        private void setAutoDetectEnableRDM() {
            var t = new Thread(() => {
                if (isSettingDetectRDM) {
                    return;
                }
                if (baseCoreNet == null) {
                    return;
                }
                while (baseCoreNet.getActiveDevIndex() < 0) {
                    Thread.Sleep(1);
                }
                baseCoreNet.setSubAutoDetectEnable_rdm(0, autoDetectRDM, true);
            });
            t.IsBackground = true;
            t.Start();
        }
    }

	#region 内部使用的类和枚举

	public class StartAddrMapPara
	{
		public string fileType = "";

		public string filePath = "";
	}

	public class LampPara
	{
		public int xPointNum = 0;			// 水平点数

		public int yPointNum = 0;			// 垂直点数

		public int subControlNum = 0;		// 分控数量

		public int totalLampNum = 0;		// 灯具数量

		public int maxChannelNum = 0;		// 最大通道数
	}

	public class DmxAddrOperEventArgs : EventArgs
	{
		public string oper = "";

		public bool success = false;

		public DmxAddrOperEventArgs(string oper, bool success)
		{
			this.oper = oper;
			this.success = success;
		}
	}

	internal class IntPair
	{
		public int val1 = 0;

		public int val2 = 0;

		public IntPair(int v1, int v2)
		{
			val1 = v1;
			val2 = v2;
		}
	}

	#endregion
}
